九齐NY8B072A单片机使用笔记(三)模拟串口RX

因为这款单片机没有硬件串口,所以需要我们自己做软件模拟串口。

用PA3作为RX,因为PA3可以作为外部输入中断EXTI1。

本人首先用轮询的方式查PA3是否从高电平跳变到低电平(起始信号),但是因为还有别的业务逻辑,导致查询到低电平的时候,不能确定此时低电平过了多少us,导致后续数据采样时间点不正确, 实时性较差。

改用中断了以后问题解决。

GPIO初始化代码如下

void Ny8b072a_Gpio_Init(void)
{
	AWUCON = C_PA1_Wakeup;	// Enable PA1 input change wakeup function
	IOSTA = 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 mode
	APHCON = (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 disable
	PORTA = 0x20;	// PA5 output high
	//PA3
	INTEDG = C_INT1_En | C_INT1_FallingEdge;	// External interrupt 1 will be set while rising edge occurs on pin PA4
	INTE = C_INT_EXT1 | C_INT_PABKey;		// Enable External interrupt & PortB input change interrupt
	
	BWUCON = C_PB5_Wakeup;	// Enable PB5 input change wakeup function
    IOSTB =  C_PB5_Input | C_PB7_Input;		// Set PB5/7 to input mode,others set to output mode
    BPHCON = (unsigned char)~( C_PB5_PHB | C_PB7_PHB);
    PORTB = 0x0F;	// PB0/1/2/3 output high
    
	IOSTC = C_PC_Output;
	PORTC = 0x03;	// PC0/1 output high
	CPHCON = (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 gpio
		
			while(1)
			{
				for(g_i = 0; g_i < 8; g_i++)
				{
					g_uart_rx_buff[g_uart_rx_length] >>= 1;
					
					App_Delay_Us(59); //104US
					
					if(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 interrupt

						INTF = (unsigned char)~(C_INT_EXT1);	// Clear INT0IF(External interrupt 0 flag bit)

						return;
					}
					else
					{
						g_uart_rx_length++;

						//wait for new start
						while (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 interrupt

					INTF = (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口改为输出即可。

  • 0
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dr_Haven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值