FR801XH 使用串1做打印,且可以接受用户手工发送数据包过去 修改参数!
-
- 实际上我不建议大家用RX FIFO去处理串口接收,除非是定长协议包,而实际是非定长数据包协议居多,且要考虑丢字节情况下,如何快速应对。我的建议代码如下:
//串口中断函数 我们配置接收字节中断试试
volatile struct uart_reg_t *uart1_reg = (volatile struct uart_reg_t *)UART1_BASE;
attribute((weak)) attribute((section("ram_code"))) void timer1_isr_ram(void)
{
timer_clear_interrupt(TIMER1);
uart0_info.rxd_flg = 0;
printf("uart0 timeout !!!!!!!!! \r\n");
timer_stop(TIMER1);
}
attribute((weak)) attribute((section("ram_code"))) void uart0_isr_ram(void)
{
uint8_t int_id;
uint8_t rx_byte;int_id = uart0_reg->u3.iir.int_id;
timer_stop(TIMER1);
if(int_id == 0x04 || int_id == 0x0c ) /* Receiver data available or Character time-out indication */
{
rx_byte = uart0_reg->u1.data;
uart0_info.packet_timeout = 2;
if(1 == uart0_info.rxd_flg)
{
uart0_info.rxd_buf[uart0_info.rxd_ctr++] = rx_byte; //
if(uart0_info.rxd_ctr == uart0_info.rxd_len)
{ //收齐 处理包
uart0_info.rxd_ctr = 0;
uart0_info.rxd_flg = 0;
uart0_info.rxd_cmd_len = uart0_info.rxd_len;
memcpy(uart0_info.rxd_cmd_buf, uart0_info.rxd_buf, uart0_info.rxd_len);
evt.event_id = 0; //串口0 事件
os_msg_post(uart01_task_id, &evt);
}
else if(3==uart0_info.rxd_ctr)
{
uart0_info.rxd_len = rx_byte + 4;//后面字节包的长度
}
else ;
}
else //== 0
{
if(0xA7 == rx_byte) //协议包头
{
uart0_info.rxd_flg = 1; //开启接收
uart0_info.rxd_ctr = 1; //接收字节计数
uart0_info.rxd_buf[0] = rx_byte;
}
}
}
else if(int_id == 0x06)
{
volatile uint32_t line_status = uart0_reg->lsr;
}
else if(int_id == 0x02)
{
if(uart0_info.txd_ctr < uart0_info.txd_len[uart0_info.txd_busy_index]) //判断当前包是否发送完毕
{
uart0_reg->u1.data = uart0_info.txd_buf[uart0_info.txd_busy_index][uart0_info.txd_ctr++];
}
else //发完一包 休息或继续下一包
{
uart0_info.txd_len[uart0_info.txd_busy_index] = 0; //清除发送包长度 表示空的 可以重新组装
if(uart0_info.txd_len[uart0_info.txd_emptypp_index]>0) //有包要发 则继续
{
if(0==uart0_info.txd_busy_index) {
uart0_info.txd_busy_index = 1;
uart0_info.txd_emptypp_index = 0;
}
else {
uart0_info.txd_busy_index = 0;
uart0_info.txd_emptypp_index = 1;
}
uart0_info.txd_ctr = 1;
uart0_reg->u1.data = 0xA7; //
}
else
{
uart0_reg->u2.ier.eti = 0;
uart0_info.tx_busy = IDLE;
}
}
}
else ;
if(uart0_info.rxd_flg)
{
timer_set_current_value(TIMER1, 0);
timer_run(TIMER1);
}
}对于有DMA发送的MCU 发送可以用DMA中断,我的这个字节发送中断 适用于更多MCU,缺点是每发1个字节,就会进串口发送结束中断1次。
严重注意: 串口接收 需要在系统设计中来的及处理,否则出现了溢出OE这些异常,记得代码里要写下清标志,否则单片就就会一直卡死这中断里,最后等看门狗复位了。- SDK V1.0.8版本 在汇编 app_boot_vectors.S 里 把串口1中断函数入口 给屏蔽了,且名字不是uart1_isr_ram
大家注意修改 import uart1_isr_ram
DCD uart1_isr_ram ; 4 2个地方 这样串口1就可以进入中断函数入口了
建议大家初始化串口1 还是放在SDK原来这个位置
void user_entry_before_ble_init(void)
{
......
// Enable UART print.
system_set_port_pull(GPIO_PA2, true);
system_set_port_mux(GPIO_PORT_A, GPIO_BIT_2, PORTA2_FUNC_UART1_RXD);
system_set_port_mux(GPIO_PORT_A, GPIO_BIT_3, PORTA3_FUNC_UART1_TXD);
uart_init(UART1, BAUD_RATE_115200);
uart_init(UART1, BAUD_RATE_2400); //即热模块 2400波特率
NVIC_SetPriority(UART1_IRQn, 1);
NVIC_EnableIRQ(UART1_IRQn);
..................
}上述使能了,串口1不但可以打印,还可以中断方式 接收字节,用于调试。 因为目前芯片的DEBUG固件存在 一定概率无法仿真的情况,(我用的是FR8018HA 其他型号不知道)
3、 目前存在问题: 定时器1的 字节超时, 我测试过定时器1 设置1S 定时间隔 都对,但是做10ms字节超时 就经常进中断,导致我丢包,我之前用了其他GD32 DA等 arm单片机 用1个定时器给1个串口做字节超时 都没发生过。但是示例1的字节超时总是打断正常收包。 我2个字节发送间隔肯定小于 超时时间的。 这个问题不得而知,耽误了我2天,很奇怪。 所以我只能做 包超时了!!
- 实际上我不建议大家用RX FIFO去处理串口接收,除非是定长协议包,而实际是非定长数据包协议居多,且要考虑丢字节情况下,如何快速应对。我的建议代码如下:
-
您好请问,用12m有什么好处?
-
@鱼的记忆 我的应用比较简单,采用12M系统运行频率,可以比24M降低几ma 功耗。我的市电断电下,是靠锂电池作为备用电源,蓝牙芯片一直运行不睡眠。
-
好的,谢谢。。。。。但是这样传输速率也变低了
-
他这个可以做睡眠的,等他接收完就睡眠,这个可以由发射端控制睡眠
-
@鱼的记忆 发射端控制睡眠? 我的蓝牙做为外设(服务端),需要广播,手机APP作为client端。
-
我以为你的蓝牙是作为从机,作为从机就可以这样做,