刚刚开始学习使用AM3359IDK板,尝试将SYS/BIOS安装包里的例程i2c_led和uart_echo合到一起,实现用串口传递数字(0-7)控制相应的led灯。但现在的问题是通过串口传递过去的数字总是不正确(如此判断的原因是不管是打印到串口终端窗口时,还是控制相应led时显示的都不对)。由于在下实在菜鸟完全搞不清楚原因,只好将调试的过程全纪录如下,望大神们不吝赐教!
(用的是sd卡的boot模式,CCS5.3.0,SYS/BIOS1.0.0.8)
这是我写的任务:
void uart_led_task(UArg a0, UArg a1)
{
Char rxChar;
Bool state;
UARTPutString(uart_instance,"hello the world of embedded system!\n\r");
UARTPutString(uart_instance,"uart_leds_practice project is running on AM3359 IDK. o(`v`)o\n\r");
UARTPutString(uart_instance,"Please input led #: ");
state = UARTGetChar(uart_instance, &rxChar);//有问题的就是这句,调用的库函
//数见下
if(state == 0)
UARTPutString(uart_instance,"Could not get char from UART\n\r");
UARTPutString(uart_instance,&rxChar);
set_led(0xff);
Task_sleep(1000);
set_led(0);
Task_sleep(1000);
while(1)
{
set_led_on(rxChar);
Task_sleep(1000);
set_led_off(rxChar);
Task_sleep(1000);
}
}
/*************************************************************************/
/*************************************************************************/
Bool UARTGetChar(UInt instance,Char *rxChar)
{
//Need error check here TODO
//UARTGet(instance,&rxChar);
UARTPutString(3,"start"); //因为是SD卡boot,除了这样打桩我不知道还有什么办法
//来Debug...求教!
unsigned int baseAddr = 0;
switch(instance)
{
case 3:
if(NULL == uart3HwiHandle )
return FALSE;
baseAddr = SOC_UART_3_REGS;
break;
case 5:
if(NULL == uart5HwiHandle )
return FALSE;
baseAddr = SOC_UART_5_REGS;
break;
default:
return FALSE;
}
UARTPutString(3,"0");
*rxChar = UARTCharGet(baseAddr ); //调用的函数见下
return TRUE;
}
/*************************************************************************/
/*************************************************************************/
//此函数位于uart_irda_cir.c文件中
signed char UARTCharGet(unsigned int baseAdd)
{
unsigned int lcrRegValue = 0;
signed char retVal = 0;
UARTPutString(3,"1");
/* Switching to Register Operational Mode of operation. */
lcrRegValue = UARTRegConfigModeEnable(baseAdd, UART_REG_OPERATIONAL_MODE);
/* Waits indefinitely until a byte arrives in the RX FIFO(or RHR). */
UARTPutString(3,"2");
while(0 == (HWREG(baseAdd + UART_LSR) & UART_LSR_RX_FIFO_E));
//UARTPutString(3,"2");
retVal = ((signed char)HWREG(baseAdd + UART_RHR));
UARTPutString(3,"3");
/* Restoring the value of LCR. */
HWREG(baseAdd + UART_LCR) = lcrRegValue;
return retVal;
}
这是运行之后的结果,在串口终端窗口中显示,前面打印的东西都是正确的
发现完全没有进入函数中(打的桩一个都没出现),于是把中间调用的那层去掉,直接调用底层的UARTCharGet:
void uart_led_task(UArg a0, UArg a1)
{
Char rxChar;
UARTPutString(uart_instance,"hello the world of embedded system!\n\r");
UARTPutString(uart_instance,"uart_leds_practice project is running on AM3359 IDK. o(`v`)o\n\r");
UARTPutString(uart_instance,"Please input led #: ");
rxChar=UARTCharGet(SOC_UART_3_REGS);//直接调用底层,SOC_UART_3_REGS是
//IDK板串口寄存器的基地址
UARTPutString(uart_instance,&rxChar);
set_led(0xff);
Task_sleep(1000);
set_led(0);
Task_sleep(1000);
while(1)
{
set_led_on(rxChar);
Task_sleep(1000);
set_led_off(rxChar);
Task_sleep(1000);
}
}
结果如下,还是输出有问题,于是用自己写的串口通信调试器试了试,发现接受到的数据完全没规律,
上图是输入数字之前显示的,最后四个字符刚好是20->” ”; 23->”#”; 3A->”:”; 20->” ”说明前面收到的信息是对的。下图是输入并发送数字6后打印出的,收到的十六进制信号为82 BF,而且重复换数字尝试后发现接收到的经常都是这两个。而且led灯也无法点亮(已排除灯坏或者点灯命令有错的可能,set_led_on(0)相应的第1个灯是会亮的)。
由于上面的尝试发现都没有进入被调用的函数,于是尝试将底层函数改个名字放到包含了main函数的.c文件中,改动如下红字部分:
void uart_led_task(UArg a0, UArg a1)
{
Char rxChar;
UARTPutString(uart_instance,"hello the world of embedded system!\n\r");
UARTPutString(uart_instance,"uart_leds_practice project is running on AM3359 IDK. o(`v`)o\n\r");
UARTPutString(uart_instance,"Please input led #: ");
rxChar=myCharGet(SOC_UART_3_REGS);
UARTPutString(3,"4");
UARTPutString(uart_instance,&rxChar);
set_led(0xff);
Task_sleep(1000);
set_led(0);
Task_sleep(1000);
while(1)
{
set_led_on(rxChar);
Task_sleep(1000);
set_led_off(rxChar);
Task_sleep(1000);
}
}
signed char myCharGet(unsigned int baseAdd)
{
unsigned int lcrRegValue = 0;
signed char retVal = 0;
UARTPutString(3,"0");
/* Switching to Register Operational Mode of operation. */
lcrRegValue = UARTRegConfigModeEnable(baseAdd, UART_REG_OPERATIONAL_MODE);
/* Waits indefinitely until a byte arrives in the RX FIFO(or RHR). */
UARTPutString(3,"1");
while(0 == (HWREG(baseAdd + UART_LSR) & UART_LSR_RX_FIFO_E));
retVal = ((signed char)HWREG(baseAdd + UART_RHR));
UARTPutString(3,"2");
/* Restoring the value of LCR. */
HWREG(baseAdd + UART_LCR) = lcrRegValue;
return retVal;
}
这时就可以输出打过的桩了,而当发送如下图所示的数字后,打过的桩也会出现,但收到的数字仍然是82 BF。。。
问题:
- SD卡boot的模式下,调试程序的办法除了笨笨的打桩以外还有什么?比如能用debug工具吗?
- 尝试过用printf在CCS console中回显,但不成功,是命令用错了吗?
- Bool UARTGetChar(UInt instance,Char *rxChar)和signed char UARTCharGet(unsigned int baseAdd)函数的用法有错吗?为什么当它不在main.c里时连调用都不行?会不会因为两个函数存储从fifo中得到的数据时,一个是Char型另一个是unsigned char而产生影响?
问题有点多,还请前辈们指点,新人拜谢!
本文来自论坛,点击查看完整帖子内容。