📄 uart.c
字号:
case MSR_DELTA_CTS:
if(IO0PIN & (1 << 11)) //CTS1 Modem -> ARM
{
WR_UREG(NET_HANDLE->base, TER, TER_DIS_TXEN);
}
else
{
WR_UREG(NET_HANDLE->base, TER, TER_EN_TXEN);
}
break;
default:
break;
}
default:
break;
}
VICVectAddr = 0x00;
}
/*******************************************************************************
* 名称:uart_usr_auto_baud()
* 功能:用户口速率自适应
* 参数:无
* 返回:true 表示成功检测到波特率并设置好波特率
false 自动波特率检测失败
*******************************************************************************/
u8 uart_usr_auto_baud(void)
{
u8 err;
auto_baud_state__ = FIRST_HIGH; //状态机初始化
Timer0_Init(); //初始化定时器0为捕捉模式
//RXD引脚选为普通输入脚
PINSEL0 &= 0xFFFFFFF3;
IO0DIR &= 0xFFFFFFFD;
CTS0_LOW();
OSSemPend(auto_baud_sem__, AUTO_FAILED_TIME, &err);
//禁止定时器0,禁止捕捉中断
T0CCR = 0;
T0TCR = TIMER_DISABLE;
if (err != OS_NO_ERR) //超时
{
return FALSE;
}
CTS0_HIGH();
return auto_baud_ok;
}
/*******************************************************************************
* 名称:optimize__()
* 功能:计算最优分频系数
* 参数:tmp_div 用于比较的分频系数
* 返回:div 最佳分频系数
*******************************************************************************/
static uf32 optimize__(uf32 tmp_div)
{
const uf32 divpool[8] = {Fpclk/(16 * 1200), Fpclk/(16 * 2400), \
Fpclk/(16 * 4800), Fpclk/(16 * 9600), \
Fpclk/(16 * 19200), Fpclk/(16 * 38400), \
Fpclk/(16 * 57600), Fpclk/(16 * 115200)};
uf32 div = FALSE, i;
tmp_div /= 32;
for(i = 0; i < 8; i++)
{
if( tmp_div > (divpool[i] - divpool[i] / 8) && \
tmp_div < (divpool[i] + divpool[i] / 8))
{
div = divpool[i];
break;
}
}
return div;
}
/*******************************************************************************
* 名称:cap_isr__()
* 功能:串口捕捉中断
* 参数:无
* 返回:无
*******************************************************************************/
void cap_isr__(void)
{
uf32 tmp;
uf32 first_low_cnt=0,sec_high_cnt=0,sec_low_cnt=0,stop_high_cnt=0;
auto_baud_ok = 0;
auto_baud_state__ = FIRST_HIGH;
CTS0_HIGH();
VICIntEnClr = EN_IRQ_TIMER0;
T0TCR = TIMER_RST;
T0TCR = TIMER_EN;
//配置捕获引脚为IO脚
PINSEL0 &= 0xFFFFFFCF;
IO0DIR &= (~0x00000004);
while(T0TC < 0x60000)
{
switch(auto_baud_state__)
{
case FIRST_HIGH:
if(IO0PIN & 0x00000004)
{
T0TCR = TIMER_RST;
T0TCR = TIMER_EN;
auto_baud_state__ = FIRST_LOW;
}
break;
case FIRST_LOW:
if(!(IO0PIN & 0x00000004))
{
first_low_cnt = T0TC;
auto_baud_state__ = SEC_HIGH;
}
break;
case SEC_HIGH:
if(IO0PIN & 0x00000004)
{
sec_high_cnt = T0TC;
auto_baud_state__ = SEC_LOW;
}
break;
case SEC_LOW:
if(!(IO0PIN & 0x00000004))
{
sec_low_cnt = T0TC;
auto_baud_state__ = STOP_HIGH;
}
break;
case STOP_HIGH:
if(IO0PIN & 0x00000004)
{
stop_high_cnt = T0TC;
auto_baud_ok = 1;
}
break;
default :
break;
}
if(auto_baud_ok) break;
}
if(auto_baud_ok)
{
if((sec_high_cnt-sec_high_cnt/10) <first_low_cnt*5 && \
first_low_cnt*5 <(sec_high_cnt+sec_high_cnt/10)&& \
(sec_low_cnt-sec_low_cnt/10) <first_low_cnt*7 && \
first_low_cnt*7 <(sec_low_cnt+sec_low_cnt/10) && \
(stop_high_cnt-stop_high_cnt/10) <first_low_cnt*8 && \
first_low_cnt*8<(stop_high_cnt+stop_high_cnt/10))
{
auto_baud_ok=3;
}
if((sec_high_cnt-sec_high_cnt/10) <first_low_cnt*6 && \
first_low_cnt*6 <(sec_high_cnt+sec_high_cnt/10)&& \
(sec_low_cnt-sec_low_cnt/10) <first_low_cnt*7 && \
first_low_cnt*7<(sec_low_cnt+sec_low_cnt/10) && \
(stop_high_cnt-stop_high_cnt/10) <first_low_cnt*8 && \
first_low_cnt*8<(stop_high_cnt+stop_high_cnt/10))
{
auto_baud_ok=4;
}
tmp = 0;
if(auto_baud_ok==3 || auto_baud_ok==4)tmp = optimize__(first_low_cnt*2);
else auto_baud_ok = 0;
if(tmp)
{
//设置用户口波特率
U0LCR |= LCR_EN_DIV;
U0DLM = tmp >> 8;
U0DLL = tmp & 0xff;
U0LCR &= 0xFFFFFF7F;
//设置网络口波特率
U1LCR |= LCR_EN_DIV;
U1DLM = tmp >> 8;
U1DLL = tmp & 0xff;
U1LCR &= 0xFFFFFF7F;
//将P0.1由I/O口改为RXD口
PINSEL0 = (PINSEL0 & 0xFFFFFFF3) | RXD0;
PINSEL0 |= 0x00000004;
IO0DIR |= 0x00000002;
OSSemPost(auto_baud_sem__);
}
}
}
/*******************************************************************************
* 名称:rts0_eint2()
* 功能:RTS0流控中断服务程序
* 参数:无
* 返回:无
*******************************************************************************/
void rts0_eint2(void)
{
if(RTS0_STATUS())
{
WR_UREG(USR_HANDLE->base, TER, TER_DIS_TXEN);
EXTPOLAR &= 0xFB; //改为下降沿触发
}
else
{
WR_UREG(USR_HANDLE->base, TER, TER_EN_TXEN);
EXTPOLAR |= 0x04; //改为上升沿触发
}
EXTINT = CLR_IRQ_EINT2;
VICVectAddr = 0x00;
}
/*******************************************************************************
* 名称:init__()
* 功能:初始化串口
* 参数:hnd 串口句柄
* 返回:无
*******************************************************************************/
static void init__(handle_t hnd)
{
extern void uart_usr_handler(void);
extern void uart_net_handler(void);
extern void rts0_eint2_handler(void);
if (hnd == USR_HANDLE)
{
CTS0_HIGH(); //给PC流控
PINSEL0 |= TXD0; //TXD0作为发送引脚,RXD0作为接收脚
//PINSEL0 |= (TXD0 | RXD0);
//初始化模拟流控信号
if(PCB_VERSION) //新版本
{
IO0DIR |= CTS0 ; //
IO0DIR &= ~RTS0;//
}
else //老版本
{
IO0DIR |= CTS0 ;
IO0DIR &= ~RTS0;
}
//初始化串口寄存器
hnd->base = USR_BASE;
WR_UREG(hnd->base, IER, IER_RBR | IER_THRE);
WR_UREG(hnd->base, FCR, FCR_FIFO | FCR_RX_8_TOUCH);
WR_UREG(hnd->base, LCR, LCR_DATA_8BITS | LCR_EN_DIV);
WR_UREG(hnd->base, LCR, LCR_DATA_8BITS);
//初始化流控中断
PINSEL0 |= RTS0_EINT2; //P0.7=>EINT2
EXTMODE |= 0x04;
//根据RTS0来决定发送的使能
if(RTS0_STATUS())
{
WR_UREG(hnd->base, TER, TER_DIS_TXEN);
EXTPOLAR &= 0xFB;
}
else
{
WR_UREG(hnd->base, TER, TER_EN_TXEN);
EXTPOLAR |= 0x04;
}
VICVectCntl8 = EN_IRQ | IRQ_EINT2;
VICVectAddr8 = (u32)rts0_eint2_handler;
EXTINT = CLR_IRQ_EINT2;
VICIntEnable |= EN_IRQ_EINT2;
//初始化用户口中断
VICVectCntl5 = EN_IRQ | IRQ_UART0;
VICVectAddr5 = (u32)uart_usr_handler;
VICIntEnable |= EN_IRQ_UART0;
}
else if (hnd == NET_HANDLE)
{
//UART1引脚功能选择
PINSEL0 |= (TXD1 | RXD1);
//RTS1、DSR1和DTR1作为IO脚
if(PCB_VERSION)
{
IO0DIR |= U1RTS1 ;
RTS1_HIGH(); //给MODEM流控
}
else
{
IO0DIR |= U1RTS1;
RTS1_HIGH(); //给MODEM流控
}
//初始化串口寄存器
hnd->base = NET_BASE;
WR_UREG(hnd->base, IER, IER_RBR | IER_THRE | IER_MODEM_STATUS);
WR_UREG(hnd->base, FCR, FCR_FIFO | FCR_RX_8_TOUCH);
WR_UREG(hnd->base, LCR, LCR_DATA_8BITS | LCR_EN_DIV);
WR_UREG(hnd->base, LCR, LCR_DATA_8BITS);
//根据CTS1来决定发送的使能
if(CTS1_STATUS())
{
WR_UREG(hnd->base, TER, TER_DIS_TXEN);
}
else
{
WR_UREG(hnd->base, TER, TER_EN_TXEN);
}
PINSEL0 |= CTS1;
//初始化网络口中断
VICVectCntl4 = EN_IRQ | IRQ_UART1;
VICVectAddr4 = (u32)uart_net_handler;
VICIntEnable = EN_IRQ_UART1;
}
// else
//{
// assert(0);
//}
hnd->tx_sem = OSSemCreate(1);
hnd->rx_sem = OSSemCreate(0);
hnd->rx_buf_ptr = NULL;
hnd->rx_buf_len = 0;
hnd->wr_buf_ptr = 0;
hnd->rd_buf_ptr = 0;
hnd->rx_buf_cnt = 0;
}
/*******************************************************************************
* 名称:uart_usr_init()
* 功能:初始化用户口(UART0)
* 参数:无
* 返回:无
*******************************************************************************/
void uart_usr_init(void)
{
init__(USR_HANDLE);
auto_baud_sem__ = OSSemCreate(0);
}
/*******************************************************************************
* 名称:uart_net_init()
* 功能:初始化网络口(UART1)
* 参数:无
* 返回:无
*******************************************************************************/
void uart_net_init(void)
{
init__(NET_HANDLE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -