因为这款单片机没有硬件串口,所以需要我们自己做软件模拟串口。
用PA3作为RX,因为PA3可以作为外部输入中断EXTI1。
本人首先用轮询的方式查PA3是否从高电平跳变到低电平(起始信号),但是因为还有别的业务逻辑,导致查询到低电平的时候,不能确定此时低电平过了多少us,导致后续数据采样时间点不正确, 实时性较差。
改用中断了以后问题解决。
GPIO初始化代码如下
void Ny8b072a_Gpio_Init(void)
{AWUCON = C_PA1_Wakeup; // Enable PA1 input change wakeup functionIOSTA = C_PA0_Input | C_PA1_Input | C_PA2_Input | C_PA3_Input | C_PA6_Input | C_PA7_Input ; // set PA0/1/3/6/7 to input modeAPHCON = (unsigned char)~( C_PA0_PHB | C_PA1_PHB | C_PA2_PHB| C_PA3_PHB | C_PA6_PHB | C_PA7_PHB ); // Enable PA0/1/3/6/7 Pull-High Resistor,others disablePORTA = 0x20; // PA5 output high//PA3INTEDG = C_INT1_En | C_INT1_FallingEdge; // External interrupt 1 will be set while rising edge occurs on pin PA4INTE = C_INT_EXT1 | C_INT_PABKey; // Enable External interrupt & PortB input change interruptBWUCON = C_PB5_Wakeup; // Enable PB5 input change wakeup functionIOSTB = C_PB5_Input | C_PB7_Input; // Set PB5/7 to input mode,others set to output modeBPHCON = (unsigned char)~( C_PB5_PHB | C_PB7_PHB);PORTB = 0x0F; // PB0/1/2/3 output highIOSTC = C_PC_Output;PORTC = 0x03; // PC0/1 output highCPHCON = (unsigned char)~( C_PC0_PHB | C_PC1_PHB);
}
用了休眠功能,EXTI也可以唤醒。
中断里面接收代码如下
volatile unsigned int g_i = 0;
unsigned char g_uart_rx_length = 0;
unsigned char g_uart_rx_buff[13] = {0};//! interrupt service routine
void isr(void) __interrupt(0)
{ if(INTFbits.INT1IF){ App_Delay_Us(26); //消抖52us//起始信号if(0 == REMOTE_RX_IO){//INTEDG = 0; //PA4 is gpiowhile(1){for(g_i = 0; g_i < 8; g_i++){g_uart_rx_buff[g_uart_rx_length] >>= 1;App_Delay_Us(59); //104USif(1 == REMOTE_RX_IO){g_uart_rx_buff[g_uart_rx_length] |= 0x80;}}App_Delay_Us(59); //104US// 结束信号if(1 == REMOTE_RX_IO){if ( ('\n' == g_uart_rx_buff[g_uart_rx_length]) || (12 == g_uart_rx_length ) ){//INTEDG = C_INT1_En | C_INT1_FallingEdge; // External interrupt 0 will be set while rising edge occurs on pin PA4//INTE = C_INT_EXT1; // Enable External interrupt & PortB input change interruptINTF = (unsigned char)~(C_INT_EXT1); // Clear INT0IF(External interrupt 0 flag bit)return;}else{g_uart_rx_length++;//wait for new startwhile (1 == REMOTE_RX_IO);App_Delay_Us(26); }}else{//INTEDG = C_INT1_En | C_INT1_FallingEdge; // External interrupt 0 will be set while rising edge occurs on pin PA4//INTE = C_INT_EXT1; // Enable External interrupt & PortB input change interruptINTF = (unsigned char)~(C_INT_EXT1); // Clear INT0IF(External interrupt 0 flag bit)return;}}}else{INTF = (unsigned char)~(C_INT_EXT1); // Clear INT0IF(External interrupt 0 flag bit) return;}}
}//@16M 2T 2.5us
//App_Delay_Us(26); //52US
//App_Delay_Us(59); //104US
void App_Delay_Us(unsigned int count)
{ for(; count > 0; count--);
}
波特率9600 每一bit的时间是1/9600=104us,所以两个延时一个是52us一个是104us
延时函数是用示波器看过的,这里配置的是16M 2T
TX因为用不上所有没有去实现,不过思路是相同的,把IO口改为输出即可。