0 / 0 / 1
Регистрация: 15.10.2015
Сообщений: 13
1

Опрос кнопки и запись в EEPROM (Си, PIC16F887)

18.10.2015, 17:41. Показов 1612. Ответов 6
Метки нет (Все метки)

Здравствуйте, написал программу по которой выполняются следующие действия: при включении выбираем одну из двух кнопок и бесконечно выполняется действие:
1.На первой - прокладывание карты с пульта и ее запоминания;
Проблема: карта записывается в ОЗУ, а не в ПЗУ, не знаю как решить данную проблему.
2. А на второй датчик препятствий - он вообще не включается.
Данная программа компилируется, плата PIC16F887.
Пожалуйста помогите решить данную проблему.
Вот сама программа если у вас есть (если у вас высвечиваются смайлики, то это "; )") :
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#include "motor.c"
#define MEM_SIZE 40
#define TMR_DX 50
#include <Motor.h>
int Adc;
char Dist;
char Txt[6];
void Read_Adc()
{
ADCON0=0b11011101;
ADCON0.GO=1;
while(ADCON0.GO);
Adc=(ADRESH*4)+(ADRESL/64);
}
// Данные с ИК пульта ДУ
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()
{
TRISA = 0b00010000;
TRISB = 0b00000001;
PORTA = 0b00000000;
PORTB = 0b00000000;
ANSEL=0xFF;
ANSELH=0x00;
for(; ;)
{
  if (!PORTA.F4)
  {
   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();
   }
 
   while(!PORTA.F4);
  }
 
  if (!PORTB.F0)
  {
  for(; ;)
  {
Delay_ms(1000);
ANSELH.F4=0;
ANSEL=0xFF;
TRISA=0xFF;
Lcd_Init(&PORTD);
Lcd_Cmd(LCD_CURSOR_OFF);
while(PORTB.F0);
Lcd_Out(1,1,"Raw Data=");
Lcd_Out(2,1,"In CM=");
while(1)
{
Read_Adc();
WordToStr(Adc,Txt);
Lcd_Out(1,10,Txt);
if(Adc<90)
{
Lcd_Out(2,10,"Out");
}
else
{
Dist=(2914/(Adc+5))-1;
WordToStr(Dist,Txt);
Lcd_Out(2,10,Txt);
}
if(Adc>300)
{
Backward(255);
Delay_ms(500);
S_Left(255);
Delay_ms(400);
}
else
{
Forward(255);
}
   while(!PORTB.F0);
  }
  }
}
}
}
}
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.10.2015, 17:41
Ответы с готовыми решениями:

hardware опрос кнопки.
Интересует есть ли железный опрос кнопки. Как энкодер самим процом обрабатывается. Хочу...

Простой опрос кнопки, но не работает
#define F_CPU 8000000L #include &lt;avr/io.h&gt; #include &lt;util/delay.h&gt; #include &lt;stdio.h&gt; #include...

Запись в EEPROM
Не могу осуществить запись в EEPROM (проверка с помощью PIC SIMULATOR IDE) под pic16f676 чтение...

Запись в EEPROM
Собираю счетчик импульсов на Miko16 и нескольких индикаторах. При отключении питания надо сохранить...

6
985 / 608 / 101
Регистрация: 15.05.2012
Сообщений: 3,592
18.10.2015, 18:50 2
Цитата Сообщение от Programma-robot Посмотреть сообщение
Проблема: карта записывается в ОЗУ, а не в ПЗУ
Бо объявлена как переменная ОЗУ.
C
1
unsigned char mem_cmd[MEM_SIZE];
Цитата Сообщение от Programma-robot Посмотреть сообщение
он вообще не включается.
Бо действие зациклено в первой кнопке.
0
0 / 0 / 1
Регистрация: 15.10.2015
Сообщений: 13
18.10.2015, 18:56  [ТС] 3
И как это исправить?
0
143 / 121 / 21
Регистрация: 14.02.2013
Сообщений: 818
18.10.2015, 20:09 4
Вам надо выучить и закрепить на практики язык программирования C.
Вы привели не ваш код.
Курсовая у вас?
0
985 / 608 / 101
Регистрация: 15.05.2012
Сообщений: 3,592
18.10.2015, 20:41 5
1. Прислушаться к совету VladimirU'а.
2. Объявить как переменную в ПЗУ.
3. Опрашивать обе кнопки.
0
0 / 0 / 1
Регистрация: 15.10.2015
Сообщений: 13
20.10.2015, 20:33  [ТС] 6
Немного переделал программу, теперь обе кнопки работают нормально, но все также остается проблема с функцией eeprom, рыскал по всему интернету, но так и не смог найти четкую информацию, пожалуйста, помогите решить эту проблему. Вот сама программа:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#include "motor.c"
 
#define MEM_SIZE 40
#define TMR_DX 50
#include <Motor.h>
int Adc;
char Dist;
char Txt[6];
// Данные с ИК пульта ДУ
unsigned char ir_data=0;
// Данные о пройденном пути
unsigned int mem[MEM_SIZE];
unsigned char mem_cmd[MEM_SIZE];
// Размер массива данных пройденного пути
unsigned char mem_size=0;
 
 
void Read_Adc()
{
ADCON0=0b11011101;
ADCON0.GO=1;
while(ADCON0.GO);
Adc=(ADRESH*4)+(ADRESL/64);
}
// Декодирование данных с пульта
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()
{
TRISA = 0b00010000;
TRISB = 0b00000001;
PORTA = 0b00000000;
PORTB = 0b00000000;
ANSEL=0xFF;
ANSELH=0x00;
Delay_ms(100);
TRISA=0xFF;
Lcd_Init(&PORTD);
Lcd_Cmd(LCD_CURSOR_OFF);
Lcd_Out(1,1,"Raw Data=");
Lcd_Out(2,1,"In CM=");
for(;;)
{
  if (!PORTA.F4)
  {
   for(;;)
   {
   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();
  }
 }
 
  }
  }
  if (!PORTB.F0)
  {
 
  for(;;)
  {
  Lcd_Out(1,1,"Raw Data=");
  Lcd_Out(2,1,"In CM=");
  Read_Adc();
 WordToStr(Adc,Txt);
 Lcd_Out(1,10,Txt);
 if(Adc<90)
 {
 Lcd_Out(2,10,"Out");
 }
 else
 {
 Dist=(2914/(Adc+5))-1;
 WordToStr(Dist,Txt);
 Lcd_Out(2,10,Txt);
 }
 if(Adc>300)
 {
 Backward(255);
 Delay_ms(500);
 S_Left(255);
 Delay_ms(400);
 }
 else
 {
 Forward(255);
 }
 
  }
  }
}
}
0
985 / 608 / 101
Регистрация: 15.05.2012
Сообщений: 3,592
21.10.2015, 18:28 7
Открываем даташит. Находим EXAMPLE 10-1: DATA EEPROM READ. Вникаем в код
Assembler
1
2
3
4
5
6
7
8
9
10
BANKSEL EEADR ;
MOVLW DATA_EE_ADDR ;
MOVWF EEADR ;Data Memory
;Address to read
BANKSEL EECON1 ;
BCF EECON1, EEPGD ;Point to DATA memory
BSF EECON1, RD ;EE Read
BANKSEL EEDAT ;
MOVF EEDAT, W ;W = EEDAT
BCF STATUS, RP1 ;Bank 0
Чуть ниже видим EXAMPLE 10-2: DATA EEPROM WRITE. И к нему тоже есть код.

Добавлено через 1 минуту
И само собой штудируем главу 10.0 DATA EEPROM AND FLASH PROGRAM MEMORY CONTROL.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.10.2015, 18:28

Опрос нажатия кнопки в стороннем приложении
Добрый день, пишу на VS2017 код, который должен выдать реакцию при клике мышкой на цифре &quot;9&quot;...

Запись в EEPROM Atmega128
Добрый день! В коде ниже проблемка: записывает только один символ и все. В чем может быть...

TIC33 и запись в EEPROM
играюсь с mega8, как обычно. и вот проблема. хочу по нажатию кнопки производить запись в eeprom. ...

Запись в STM8 EEPROM
Переменные: #pragma location=0x004001 //stort eeprom address __no_init int16_t CorrectionValue; ...

Запись/чтение EEPROM
Первый раз столкнулся со встроенным еепромом, немного погуглил, понял что есть 3 пути работы с ним...

Запись в Serial EEPROM.
Пишу в память. void LOGGER_Write(uint32_t address, uint32_t lenght, uint8_t *data) { #if...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru