MTK之UART串口收发数据
来源:互联网 发布:gta5精简优化版 编辑:程序博客网 时间:2024/06/05 10:24
寄存器
UARTn_RBR: Rx Buffer Register,通过读取该寄存器接收数据。要求LCR[7]=0。
UARTn_THR: Tx Holding Register,数据先写入该寄存器,再送至PC端。要求LCR[7]=0。
UARTn_IER: Interrupt Enable Register,IER[3:0] are modified when LCR[7]=0. IER[7:4] are modified when LCR[7]=0 & EFR[4]=1.
EDSSI: 如果MSR[4:1] 有数据,产生中断。IER[3]=1
ERBFI: 如果Rx Buffer有数据,产生中断。IER[0]=1
UARTn_IIR: Interrupt Identification Register
Rx Data Received: Rx Data received or RX Trigger Level reached. IIR[5:0] = 000100
Rx Data Timeout: Timeout on character in RX FIFO. IIR[5:0] = 001100
串口流程
UART1_HISR //根据IIR类型判断tx or rx
// UART_IIR_CTI
UART1_HISR
=> UART_RecHandler(&UARTPort[uart_port1]);
=> UARTPort[UARTData->port_no].rx_cb(UARTData->port_no);
=> UART_dafault_rx_cb
=> UART_sendilm(port, MSG_ID_UART_READY_TO_READ_IND);
// from MOD_DRV_HISR to UARTPort[port].ownerid
默认发消息到MOD_TST_READER,处理后再调用
=> DclSerialPort_Control(handle, SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*)&data_getbyte);
最终调用DCL_STATUS UART_Handler(DCL_DEV dev, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data) // return buffer
// UART_IIR_THRE
UART1_HISR
=> UART_TrxHandler(&UARTPort[uart_port1]);
=> UARTPort[UARTData->port_no].tx_cb(UARTData->port_no);
=> UART_datafault_tx_cb
=> UART_sendilm(port, MSG_ID_UART_READY_TO_WRITE_IND);
// from MOD_DRV_HISR to UARTPort[port].ownerid // MOD_ATCI==41
默认发消息到MOD_TST_READER,处理后再调用
=> DclSerialPort_Control(handle, SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*)&data_getbyte);
最终调用DCL_STATUS UART_Handler(DCL_DEV dev, DCL_CTRL_CMD cmd, DCL_CTRL_DATA_T *data) // send buffer
软件处理:直接发送MSG_ID_UART_READY_TO_READ_IND到MOD_ATCI,会调用UART_Handler中SIO_CMD_GET_BYTES获取AT命令,在此处给指针赋值并且中断从串口读取数据的流程,完成后MOD_ATCI会继续调用UART_Handler中SIO_CMD_PUT_BYTES输入AT命令返回的结果,在此处可以拷贝一份传给软件处理,此处同时会传递给串口往外输出。
软件流程
因为MSG_ID_UART_READY_TO_READ_IND属于驱动层的消息,通过串口发送AT指令的过程为MOD_DRV_HISR->MOD_TST_READER。如果在MMI层中设置响应函数来响应UART的READY TO READ消息,这时AT指令无效,直接发往MMI层。由于MMI层截获了这个消息,因此先响应MMI层的响应函数,如果在读取UART的buffer后将其清空,MOD_TST_READER自然得不到AT指令,因此无法做出任何AT响应。值得注意的是,所有串口在接到字符后响应的都是该消息,因此在读取的时候需要判断是否来自所需串口的信息。
打开串口
(1) 禁止休眠
(2) 设置MSG_ID_UART_READY_TO_READ_IND消息的响应函数
(3) 将串口所属MOD切换至将要使用的MOD(UART_GetOwnerID, UART_SetOwner)
(4) 设置串口参数,波特率等(UART_SetDCBConfig)
(5) 清空对应串口的接收Buffer(UART_ClrRxBuffer)
读取串口信息
(1) UART_GetBytesAvail
(2) UART_GetBytes
(3) 读完之后清空接收Buffer(UART_ClrRxBuffer)
向串口写信息
(1) 清空设备输入、输出FIFO(UART_Purge)
(2) 清空发送、接收Buffer(UART_ClrTxBuffer,UART_ClrRxBuffer)
(3) 写入数据UART_PutBytes
关闭串口
(1) 将所使用的串口MOD设置为原来的MOD
(2) 使能睡眠
#define GC_UART_PORT uart_port1#define MAX_ECHO_PACKET_LEN 255extern module_type U_GetOwnerID(UART_PORT port);extern void U_ClrTxBuffer(UART_PORT port, module_type ownerid);extern void U_ClrRxBuffer(UART_PORT port, module_type ownerid);static kal_uint8 ghSleepMode;static module_type gnOrigUartOwner;static kal_bool gbUartInitialized = KAL_FALSE;static kal_bool gbUartEchoStarted = KAL_FALSE;static U16 gwLenUartBuffer = 0;static U8 gabyUartBuffer[MAX_ECHO_PACKET_LEN];static void gc_init_uart(void){ if (gbUartInitialized) return; //禁止休眠 ghSleepMode = L1SM_GetHandle(); L1SM_SleepDisable(ghSleepMode); //切换MOD,设置串口参数、波特率等 gnOrigUartOwner = UART_GetOwnerID(GC_UART_PORT); U_SetOwner(GC_UART_PORT, MOD_MMI); U_SetBaudRate(GC_UART_PORT, UART_BAUD_115200, MOD_MMI); //设置MSG_ID_UART_READY_TO_READ_IND消息的响应函数 ClearProtocolEventHandler(MSG_ID_UART_READY_TO_READ_IND); SetProtocolEventHandler(mmi_gc_uart_readyToRead_ind_handler, MSG_ID_UART_READY_TO_READ_IND); gbUartInitialized = KAL_TRUE; }void mmi_gc_uart_readyToRead_ind_handler(void *msg){ uart_ready_to_read_ind_struct* uart_rtr_ind = (uart_ready_to_read_ind_struct*) msg; kal_uint8 status; gwLenUartBuffer = DT_HAL_UART_GetBytes(uart_port1, gabyUartBuffer, sizeof(gabyUartBuffer), &status, MOD_MMI); DT_HAL_UART_PutBytes(uart_port1, gabyUartBuffer, gwLenUartBuffer, MOD_MMI);}//////////////////////static U16 read_from_uart(U8 *pbyBuf, U16 wLenMax, UART_PORT hPort, module_type hOwner){ U16 wLenAvail; U16 wLenRead; U16 wLenRet = 0; U8 byStatus = 0; //收取数据,超过最大包长的数据将简单丢弃 while (wLenAvail = U_GetBytesAvail(hPort)>0 && wLenRet < wLenMax) { if (wLenAvail + wLenRet > wLenMax) wLenAvail = wLenMax - wLenRet; wLenRead = U_GetBytes(hPort, (kal_uint8*) (pbyBuf + wLenRet), (kal_uint16)wLenAvail, &byStatus, hOwner); wLenRet += wLenRead; } //读完后,清空串口接收Buffer U_ClrRxBuffer(hPort, hOwner); return wLenRet;}static U8 write_to_uart(U8 *pbyBuf, U16 wLenBuf, UART_PORT hPort, module_type hOwner){ U16 wSent = 0; U8 bRet = FALSE; // 发送前清空输入、输出FIFO U_Purge(hPort, RX_BUF, hOwner); U_Purge(hPort, TX_BUF, hOwner); // 清空发送、接收Buffer U_ClrTxBuffer(hPort, hOwner); U_ClrRxBuffer(hPort, hOwner); //写入数据 wSent = U_PutBytes(hPort, (kal_uint8 *)pbyBuf, (kal_uint16)wLenBuf, hOwner); if (wSent == wLenBuf) bRet = TRUE; return bRet;}static void exit_uart(){ if (gbUartInitialized) { //恢复原有端口占用者 U_SetOwner(GC_UART_PORT, (kal_uint8)gnOrigUartOwner); L1SM_SleepEnable(ghSleepMode); gbUartInitialized = KAL_FALSE; }}static void mmi_gc_uart_readyToRead_ind_handler(void *msg){ uart_ready_to_read_ind_struct* uart_rtr_ind = (uart_read_to_read_ind_struct*)msg; if (KAL_FALSE == gbUartEchoStarted || GC_UART_PORT != uart_rtr_ind->port || MOD_MMI != UART_GetOwnerID(uart_rtr_ind->port)) return; gwLenUartBuffer = read_from_uart(gabyUartBuffer, sizeof(gabyUartBuffer), GC_UART_PORT, MOD_MMI); uart_echo_process(); }static void start_uart_echo(void){ S8 strHelllo[] = "Hello World Uart Echo Example Started!\r\n"; if (gbUartEchoStarted) return; gc_init_uart(); write_to_uart((kal_uint8*)strHello, (kal_uint16)strlen(strHello), GC_UART_PORT, MOD_MMI); gbUartEchoStarted = KAL_TRUE; SetKeyHandler(stop_uart_echo, KEY_LSK, KEY_EVENT_UP);}static void uart_echo_process(void){ U8 i; char my_data_buffer[256]; for (i=0; i<gwLenUartBuffer; i++) { AnsiiToUnicodeString((S8*)my_data_buffer, (S8*)gabyUartBuffer); if (my_data_buffer[0]=='p'&&my_data_buffer[2]=='t') { S8 strByte[] = "Play tone successfully\r\n"; write_to_uart((kal_uint8*)strByte, (kal_uint16)strlen(strByte), GC_UART_PORT, MOD_MMI); } else gabyUartBuffer[i]-=0x20; } write_to_uart(gabyUartBuffer, gwLenUartBuffer, GC_UART_PORT, MOD_MMI);}static void stop_uart_echo(void){ S8 strBye[] = "Hello World Uart Echo Example Stop!\r\n"; if (gbUartEchoStarted) { write_to_uart((kal_uint8*)strByte, (kal_uint16)strlen(strBye), GC_UART_PORT, MOD_MMI); gbUartEchoStarted = KAL_FALSE; SetKeyHandler(start_uart_echo, KEY_LSK, KEY_EVENT_UP); } exit_uart();}void mmi_HelloWorld_entry(void){ SetKeyHandler(start_uart_echo, KEY_LSK, KEY_EVENT_UP);}
- MTK之UART串口收发数据
- MTK之UART串口收发数据
- Tiny4412裸机程序之UART收发数据
- MTK 解决蓝牙串口MMI不能收发数据的问题
- UART数据收发波形
- tiny4412 UART 收发数据
- mtk 串口读取uart log
- BLE协议栈之串口数据收发
- 串口收发数据
- 监控串口数据收发
- 串口数据收发问题
- 串口收发数据1
- 串口多路复用收发数据
- ZigBee串口收发数据
- 单片机串口收发数据
- c#串口收发数据
- 串口通信 收发数据
- 2串口收发数据
- 3D Touch
- 总结一下java中的位操作,运算优先级
- ApachePOI导出exce,设置单元格风格的属性和设置字体风格的属性的两个工具类,POI宽度和excel 像素转换
- 如何求两个矩形相交面积
- 查找--静态查找与动态查找
- MTK之UART串口收发数据
- SDAU练习二1011
- 不用导入SDK就可实现导航--URI方式跳转到各类地图进行导航
- 朴素贝叶斯的实际应用
- 数据结构,堆的学习
- android文件操作
- bzoj 1067 [SCOI2007]降雨量
- nyoj27 水池数目
- 162. Find Peak Element