我正在尝试使用 ATMEGA328P 实现中断驱动的 UART 通信。我需要实现的是通过 UART 发送命令(字符数组),以便将值提取到main
例程中的变量中,以便我可以在电路中编程行为。
我发送的数据格式如下2 255 0 255 0 0 255 1000
:(用于 RGB LED 灯)这描述long int
了mode
、2 RGB 颜色和duration
.
到目前为止,这就是我所拥有的main
:
while(1)
{
if(rxFlag==1){
char * pEnd;
mode = strtol(buffer,&pEnd,10);
Ri = strtol (pEnd, &pEnd,10);
Gi = strtol (pEnd, &pEnd,10);
Bi = strtol (pEnd, &pEnd,10);
Rf = strtol (pEnd, &pEnd,10);
Gf = strtol (pEnd, &pEnd,10);
Bf = strtol (pEnd, &pEnd,10);
duration = strtol (pEnd,NULL,10);
rxFlag=0;
}
switch(mode){
case 1: // fixed color
fixed(Rf, Gf, Bf);
break;
case 2: // yoyo pulse
yoyo(Ri,Gi,Bi,Rf,Gf,Bf,duration);
break;
default:// red blinky
fixed(0,255,255);
_delay_ms(500);
fixed(255,255,255);
_delay_ms(500);
break;
}
}
以及处理接收的 ISR(中断服务程序):
ISR(USART_RX_vect)
{
while ( !(UCSR0A & (1<<RXC0)) );
if (rxn==80){ // if BUFFER_SIZE is reached, reset to start of buffer.
rxn=0;
}
buffer[rxn++] = UDR0; // increment rxn and return new value.
if(buffer[rxn]=='\0'){
rxFlag=1; // notify main of receipt of data.
}
}
如您所见,我仅在检测到\0
流末尾的 时才尝试更新变量的值。
这就像(在 ISR 中):
- 读取传入的字节并将其存储在最多 80 字节长的缓冲区中
- 如果一个
\0
进来,让主知道它有新数据要处理
在main
:
- 如果有新数据,将缓冲区分成
long int
并存储值 - 清除新数据标志
- 根据新的价值观行事。
问题是这并没有按照我的意愿进行,我有点迷路了。我知道我的switch
陈述可以正常工作,因为变量具有正确的值。我已将问题缩小到通信/缓冲区填充阶段被破坏或变量值的提取被破坏,但不确定是哪一个或两者都有。
任何人都可以分享任何见解吗?