29.10.2015, 14:05
|
|
Прохожий
Регистрация: 29.10.2015
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Программа пульта и функции eeprom
Здравствуйте, написал программу, в которой действия с пульта запоминаются в ОЗУ, а не в ПЗУ, но не знаю как это сделать с использованием функции eeprom.
Микроконтроллер: PIC16F887. Компилятор: MicroC.
Вот сама программа:
Код:
|
#include "motor.c"
#define MEM_SIZE 40
#define TMR_DX 50
// Данные с ИК пульта ДУ
unsigned char ir_data=0;
// Данные о пройденном пути
unsigned int mem[MEM_SIZE];
unsigned char mem_cmd[MEM_SIZE];
// Размер массива данных пройденного пути
unsigned char mem_size=0;
// Декодирование данных с пульта
void decode()
{
if(ir_data=='a' || ir_data=='A') ir_data=1;
else if(ir_data=='b' || ir_data=='B') ir_data=2;
else if(ir_data=='c' || ir_data=='C') ir_data=3;
else if(ir_data=='d' || ir_data=='D') ir_data=4;
else ir_data=0;
}
// Приём данных с пульта
void interrupt()
{
char i;
// Проверка флага прерывания
if(INTCON.INTF)
{
Delay_us(416);
for(i=0;i‹8;i++)
{
Delay_us(833);
// Сдвиг данных на 1 бит вправо
ir_data = ir_data››1;
// Если на входе RB0 1, то в конец ir_cmd добавить 1
if((PORTB & 0x01)==1) ir_data = ir_data | 0x80;
}
Delay_us(833);
decode(); // Декодировать данные
// Сбросить флаг прерывания
INTCON.INTF = 0;
}
}
// Очистка памяти
void mem_clear()
{
unsigned int i;
for(i=0;i‹MEM_SIZE;i++)
{
mem[i]=0;
mem_cmd[i]=0;
}
}
void _go()
{
unsigned int i,j;
unsigned char cmd;
unsigned int tmr;
for(i=0;i‹=mem_size;i++)
{
cmd = mem_cmd[i];
tmr = mem[i];
if(cmd==1)
{
m_left_bwd();
m_right_bwd();
}
else if(cmd==2)
{
m_left_bwd();
m_right_fwd();
}
else if(cmd==3)
{
m_left_fwd();
m_right_bwd();
}
else if(cmd==4)
{
m_left_fwd();
m_right_fwd();
}
for(j=0;j‹tmr;j++) Delay_ms(TMR_DX+10);
}
m_left_stop();
m_right_stop();
}
void main()
{
unsigned char key;
// RB0 в цифровой вход
ANSELH.F4 = 0;
TRISA.F4=1;
// Прерывание происходит по спаду уровня сигнала
OPTION_REG.INTEDG = 0;
// Разрешить прерывания по изменению уровня сигнала INT/PB0
INTCON.INTE = 1;
// Разрешить прерывания
INTCON.GIE = 1;
// Инициализируем двигатели
m_init();
// Настроить вывод светодиода и мигнуть им когда очиститься память
TRISB.F3=0;
PORTB.F3=1;
mem_clear();
Delay_ms(200);
PORTB.F3=0;
for(;;)
{
Delay_ms(TMR_DX);
if(!PORTA.F4) _go(); // Запускаем движение по карте
if(ir_data!=0)
{
//Загружаем данные из временной переменной ir_data
key = ir_data;
ir_data = 0;
// Если команда отличается от предыдущей
if(mem_cmd[mem_size]!=key)
{
// Выбираем следующую ячейку памяти
mem_size++;
if(mem_size==MEM_SIZE)
{
PORTB.F3=1; // Зажигаем светодиод
while(1) if(!PORTA.F4) _go(); // Запускаем движение по карте
}
// Сохраняем команду для её последующего сравнения
mem_cmd[mem_size]=key;
// Увеличиваем время простоя команды
mem[mem_size]++;
}
else
{
// Увеличиваем время простоя команды
mem[mem_size]++;
}
if(key==1)
{
m_left_bwd();
m_right_bwd();
}
else if(key==2)
{
m_left_bwd();
m_right_fwd();
}
else if(key==3)
{
m_left_fwd();
m_right_bwd();
}
else if(key==4)
{
m_left_fwd();
m_right_fwd();
}
}
else
{
m_left_stop();
m_right_stop();
}
}
} |
|
|
|
|
29.10.2015, 14:18
|
|
Заблокирован
Регистрация: 17.07.2010
Адрес: мурмурляндия
Сообщений: 10,715
Сказал спасибо: 189
Сказали Спасибо 3,199 раз(а) в 2,074 сообщении(ях)
|
Re: Программа пульта и функции eeprom
а зачем команды пульта запоминать? и тем более в пзу? лог пульта чтоль вести?))
|
|
|
|
29.10.2015, 16:47
|
|
Прохожий
Регистрация: 29.10.2015
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Программа пульта и функции eeprom
Просто необходимо, если можете помочь, то буду очень благодарен
|
|
|
|
29.10.2015, 17:38
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,220 раз(а) в 1,319 сообщении(ях)
|
Re: Программа пульта и функции eeprom
Стр 111 даташита, раздел 10 "EEPROM", а так же подраздел 10.1.3 - "запись в еепром".
http://ww1.microchip.com/downloads/e...Doc/41291D.pdf
Вначале выставляется адрес ячейки ЕЕПРОМ (от 0 до 255) в регистре EEADR, в регистр EEDAT заносится байт, который нужно будет записать в еепром, затем в регистре EECON1 битом EEPGD=0 переключатеся на обращение к еепром, а битом WREN=1 разрешается запись в еепром и после этого выполняется последовательная запись в регистр EECON2 байтов 0х55 и 0хАА - это необходимая процедура, придуманная для защиты от случайной перезаписи еепром. После этого запускается сам процесс записи битом WR=1 в регистре EECON1. По окончании записи, через несколько миллисекунд (по-моему, 10 мс, забыл уже) выставится бит прерывания, сигнализирующий о завершении процесса записи. После этого можно записывать новые данные в другую ячейку еепром.
|
|
|
|
29.10.2015, 20:49
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.12.2007
Сообщений: 1,198
Сказал спасибо: 70
Сказали Спасибо 80 раз(а) в 69 сообщении(ях)
|
Re: Программа пульта и функции eeprom
Там всего две функции
unsigned short EEPROM_Read(unsigned short address);
и
void EEPROM_Write(unsigned short address, unsigned short data);
не чего сложного.
|
|
|
|
29.10.2015, 21:37
|
|
Прохожий
Регистрация: 29.10.2015
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Программа пульта и функции eeprom
Vavan1983, если я правильно вас понял то мне нужно убрать какой-то из пунктов программы и вставить эти фразы
|
|
|
|
29.10.2015, 22:09
|
|
Почётный гражданин KAZUS.RU
Регистрация: 26.12.2007
Сообщений: 1,198
Сказал спасибо: 70
Сказали Спасибо 80 раз(а) в 69 сообщении(ях)
|
Re: Программа пульта и функции eeprom
Сообщение от Programma
|
Vavan1983, если я правильно вас понял то мне нужно убрать какой-то из пунктов программы и вставить эти фразы
|
Эти "фразы" называют функции языка программирования си.
Попробуйте изучить язык программирования C используя для этого самоучители по С.
|
|
|
|
30.10.2015, 06:24
|
|
Прохожий
Регистрация: 29.10.2015
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Программа пульта и функции eeprom
Вот посмотрите:
Код:
|
#include "motor.c"
#define MEM_SIZE 40
#define TMR_DX 50
// Данные с ИК пульта ДУ
unsigned short ir_data=0;
// Данные о пройденном пути
unsigned short mem[MEM_SIZE];
unsigned short mem_cmd[MEM_SIZE];
// Размер массива данных пройденного пути
unsigned char mem_size=0;
Eeprom_Write(mem_size);
// Декодирование данных с пульта
void decode()
{
if(ir_data=='a' || ir_data=='A') ir_data=1;
else if(ir_data=='b' || ir_data=='B') ir_data=2;
else if(ir_data=='c' || ir_data=='C') ir_data=3;
else if(ir_data=='d' || ir_data=='D') ir_data=4;
else ir_data=0;
}
// Приём данных с пульта
void interrupt()
{
char i;
// Проверка флага прерывания
if(INTCON.INTF)
{
Delay_us(416);
for(i=0;i‹8;i++)
{
Delay_us(833);
// Сдвиг данных на 1 бит вправо
ir_data = ir_data››1;
// Если на входе RB0 1, то в конец ir_cmd добавить 1
if((PORTB & 0x01)==1) ir_data = ir_data | 0x80;
}
Delay_us(833);
decode(); // Декодировать даннные
// Сбросить флаг прерывания
INTCON.INTF = 0;
}
}
// Очистка памяти
void mem_clear()
{
unsigned int i;
for(i=0;i‹MEM_SIZE;i++)
{
mem[i]=0;
mem_cmd[i]=0;
}
}
void _go()
{
unsigned int i,j;
unsigned char cmd;
unsigned int tmr;
for(i=0;i‹=mem_size;i++)
{
cmd = mem_cmd[i];
tmr = mem[i];
if(cmd==1)
{
m_left_bwd();
m_right_bwd();
}
else if(cmd==2)
{
m_left_bwd();
m_right_fwd();
}
else if(cmd==3)
{
m_left_fwd();
m_right_bwd();
}
else if(cmd==4)
{
m_left_fwd();
m_right_fwd();
}
for(j=0;j‹tmr;j++) Delay_ms(TMR_DX+10);
}
m_left_stop();
m_right_stop();
}
void main()
{
unsigned char key;
// RB0 в цифровой вход
ANSELH.F4 = 0;
TRISA.F4=1;
// Прерывание происходит по спаду уровня сигнала
OPTION_REG.INTEDG = 0;
// Разрешить прерывания по изменению уровня сигнала INT/PB0
INTCON.INTE = 1;
// Разрешить прерывания
INTCON.GIE = 1;
// Инициализируем двигатели
m_init();
// Настроить вывод светодиода и мигнуть им когда очиститься память
TRISB.F3=0;
PORTB.F3=1;
mem_clear();
Delay_ms(200);
PORTB.F3=0;
for(;;)
{
Delay_ms(TMR_DX);
if(!PORTA.F4) _go(); // Запускаем движение по карте
if(ir_data!=0)
{
//Загружаем данные из временной переменной ir_data
key = ir_data;
ir_data = 0;
// Если команда отличается от предыдущей
if(mem_cmd[mem_size]!=key)
{
// Выбираем следующую ячейку памяти
mem_size++;
if(mem_size==MEM_SIZE)
{
PORTB.F3=1; // Зажигаем светодиод
while(1) if(!PORTA.F4) _go();
PORTA.F4 = Eeprom_Read (mem_size);// Запускаем движение по карте
}
// Сохраняем команду для её последующего сравнения
mem_cmd[mem_size]=key;
// Увеличиваем время простоя команды
mem[mem_size]++;
}
else
{
// Увеличиваем время простоя команды
mem[mem_size]++;
}
if(key==1)
{
m_left_bwd();
m_right_bwd();
}
else if(key==2)
{
m_left_bwd();
m_right_fwd();
}
else if(key==3)
{
m_left_fwd();
m_right_bwd();
}
else if(key==4)
{
m_left_fwd();
m_right_fwd();
}
}
else
{
m_left_stop();
m_right_stop();
}
}
} |
|
|
|
|
30.10.2015, 14:19
|
|
Прохожий
Регистрация: 29.10.2015
Сообщений: 7
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Re: Программа пульта и функции eeprom
Если честно пробовал очень много способов:
даташит, eeprom_editor, функции их вставка до бесконечного цикла, обращался в различные форумы, но никто не может четко объяснить, что делать в моей ситуации.
Но многие пишут что нужно в этой функции объявить переменную как в ПЗУ:
unsigned char mem_cmd[MEM_SIZE];
Но я искал как это сделать и не нашел. Подскажите как можно изменить переменную или еще что сделать.
|
|
|
|
30.10.2015, 14:38
|
|
Заблокирован
Регистрация: 22.04.2014
Сообщений: 0
Сказал спасибо: 15
Сказали Спасибо 366 раз(а) в 284 сообщении(ях)
|
Re: Программа пульта и функции eeprom
Могу предположить, что вас просто никто не понимает. Попробуйте поставить вопрос по другому и свести вопрос к конкретной проблеме, а не к "Вот посмотрите". На что там смотреть?
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 17:28.
|
|