uart0.c

来自「这个是一个带有IC卡」· C语言 代码 · 共 197 行

C
197
字号

#include <stdio.h>
#include <stdlib.h>
#include "config.h"

#include "main.h"

#define __SRC

#include "UART0.h"

#undef	__SRC

static volatile uint8  recv_cnt = 0;
static uint8 recv_buf[32];

//extern uint8 volatile ui8_FLG_TransMode;
//在main函数中定义


void UART0_Init(void)
{
	
    uint16 Fdiv;        
    PINSEL0 =(PINSEL0 & 0xfffffff0) | 0x05;    /* 选择管脚为UART0 */
    U0LCR = 0x80;                               /* 允许访问分频因子寄存器 */
    Fdiv = (Fpclk / 16) / UART0_BPS;            /* 设置波特率 */
  	// Fdiv = (Fpclk / 16) / 115200; 
    U0DLM = Fdiv / 256;							
	U0DLL = Fdiv % 256;						
	U0LCR = 0x3|				// 字符长度:00(5位字符)01(6位)10(7位)11(8位)
    		(0<<2)|				// 停止位选择:0(1个停止位)1(2位停止位)
    		(0<<3)|				// 寄偶使能:0(禁止)1(使能)
    		(0<<5)|			    // 寄偶选择:00(奇数)01(偶数)10(强制为1)11(强制为0)
    		(0<<6)|				// 间隔控制:0(禁止间隔发送)1(使能间隔发送)
    		(0<<7);             // 除数锁存访问位:0(禁止访问除数锁存)
    		//设置为:8,n,1	
   
	                            
	U0FCR = 0x07;         		/* 初始化FIFO,为1个字节的缓存 */	               
	U0IER = 0x03;				/* 允许接收和发送中断 */
	
		/* 设置UART中断 */
	VICIntSelect =0x00000000;	//所有的通道都设置为IRQ模式
	
	VICVectCntl0 = 0x20|6;		//中断控制寄存器,UART0为SLOT0	
	VICVectAddr0 = (uint32)IRQ_UART0;//
	VICIntEnable = 1<<6;		//使能UART0中断
	
}



__irq void IRQ_UART0(void)
{
	uint8 i;
	uint8 ui8_Uart0IntNum;		//用来存放串口的中断类型
	ui8_Uart0IntNum = U0IIR;	//获取中断源的值	
	
	if(ui8_Uart0IntNum & 0x04)	//当为接收数据有效的中断时		
	{			
		if((ui8_RecvNewDataFlg == UART0_SDBUFNUSE)&&(ui8_RecvCounter < UART0_LENGTH_RECVDATA))	
		{		
			if(recv_cnt != 0) {
				memcpy(&ui8_RecvDataBuf[ui8_RecvCounter], recv_buf, recv_cnt);
				ui8_RecvCounter += recv_cnt;
				recv_cnt = 0;
			}	
			if(U0RBR != UART0_RECV_DATAEND)	
			{
				ui8_RecvDataBuf[ui8_RecvCounter] = U0RBR;
				ui8_RecvCounter++;
			}
			else			
			{
				ui8_RecvDataBuf[ui8_RecvCounter] = U0RBR;
				ui8_RecvCounter++;
				ui8_RecvNewDataFlg = UART0_SDBUFIUSE;		//等待处理
			}//	if(U0RBR==UART0_DATA0A)			
		}//if((ui8_RecvNewDataFlg==0)&&(ui8_RecvCounter<UART0_LENGTH_RECVDATA))
		else {
			recv_buf[recv_cnt] = U0RBR;
			recv_cnt++;
		}
			// if(ui8_RecvCounter == UART0_LENGTH_RECVDATA)
			//ClearRecvDataBuf();
		//else if(ui8_RecvNewDataFlg == UART0_SDBUFNUSE && timer > 10)	
				
		i=U0RBR;//进入中断后,后必须清一下对应的中断,防止中断死锁。				
	}//if(ui8_Uart0IntNum&0x04)//当为接收数据有效的中断时		
	
	
	if(ui8_Uart0IntNum & 0x02)//用中断的方式,发送数据	
	{
		if((ui8_SendNewDataFlg==UART0_SDBUFIUSE)&&(ui8_SendCounter < UART0_LENGTH_SENDDATA))//发送数据的标志为0时发送,即在没有发送完成的时候发送
		{
			if(ui8_SendDataBuf[ui8_SendCounter] != UART0_SEND_DATAEND)
			{//在没有检测到结束符时发送在缓存中的内容
				U0THR = ui8_SendDataBuf[ui8_SendCounter];	
				ui8_SendCounter++;				
			}
			//if(ui8_SendDataBuf[ui8_SendCounter] == UART0_DATAEND)
			else
			{//检测到结束符时,发送完后即置位发送缓存的标志位
				U0THR = UART0_SEND_DATAEND;	
				ui8_SendNewDataFlg = UART0_SDBUFNUSE;	//发送完毕标志			
			}						
		}			
		i=U0IIR;//进入中断后,后必须清一下对应的中断,防止中断死锁。	
	}//if(ui8_Uart0IntNum&0x02)//用中断的方式,发送数据		
	VICVectAddr=0x00;//通知处理器中断完成
}//__irq void IRQ_UART0(void)


void ClearSendDataBuf(void)
{
	uint8 i;
	ui8_SendCounter=0;
	ui8_SendNewDataFlg = UART0_SDBUFNUSE;		//不在使用中	
	for(i=0;i<UART0_LENGTH_SENDDATA;i++)
	{
		
		ui8_SendDataBuf[i]=0;
	}
}

void ClearRecvDataBuf(void)
{
	uint8 i;
	ui8_RecvCounter = 0;	
	ui8_RecvNewDataFlg  = 0;	
	for(i=0;i<UART0_LENGTH_RECVDATA;i++)
	{
		
		ui8_RecvDataBuf[i]=0;
	}
	
}

void StartDataSend(void)
{
	if(UART0_SDBUFNUSE == ui8_SendNewDataFlg)
	{
		ui8_SendCounter = 0;							//发送数据计数器清零	
		ui8_SendNewDataFlg = UART0_SDBUFIUSE;			//在使用中
		U0THR = ui8_SendDataBuf[0];		
		ui8_SendCounter++;
	}
}


uint8 Uart0_Send_String(const char *str, uint8 strlen)
{
	int i;
	
	if(str == NULL || strlen > UART0_LENGTH_SENDDATA)
		return -1;
	
	while(ui8_SendNewDataFlg == UART0_SDBUFIUSE);		//等待前次发送完毕
	
	ClearRecvDataBuf();
	for(i = 0; i < strlen; i++)
		ui8_SendDataBuf[i] = *(str + i);
	
	StartDataSend();	
	
	return 0;
}

uint8 Uart0_recv_String(char *str, uint8 strlen)
{
	uint8 i,count;
	
	if(str == NULL)
		return -1;
	
	if(ui8_RecvNewDataFlg == UART0_SDBUFIUSE) {
			memset(str, 0, strlen);
			
			count = (ui8_RecvCounter >= strlen ? strlen : ui8_RecvCounter);	
			for(i = 0; i < count; i++)
				*(str + i) = ui8_RecvDataBuf[i];
				
			*(str + count) = '\0';	
									
			ClearRecvDataBuf();
			return count;
	}
	
	return 0;
}





       

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?