本帖最后由 leonbaichi 于 2011-9-3 01:27 编辑
之前学习过菜农叔的无限FIFO,那叫一个了得,自己在学串口的时候想顺便整整M0的FIFO,仿造着试试。结果碰了一天的壁。感谢JOHN LEE老师,SWALLOW0322以及电子WHITE_CAI等坛友的帮助。好歹让我找到了北,虽然没整出来,程序贴在下面,请大家帮忙看看。抛开程序写的好不好不谈。只要功能实现了先,就很开心了。
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvUART.h"
#include "DrvSYS.h"
typedef struct {
volatile unsigned char RxBuffer[256], TxBuffer[256];
volatile unsigned char RxCount, TxCount;
volatile unsigned char RxdCount, TxdCount;
volatile unsigned char TxBusy;
}UartStruct;
UartStruct Uart;
void UART0Callback(uint32_t data);
void Sys_Init()
{
UNLOCKREG(); //芯片注册解锁
SYSCLK->PWRCON.XTL12M_EN = 1;// 设定12M外部晶振
DrvSYS_Delay(5000); //等待时钟就绪
DrvGPIO_Open(E_GPB, 10, E_IO_OUTPUT); // 设置GPB10端口为输出模式
DrvGPIO_ClrBit(E_GPB, 10); // 清GPB10端口 蜂鸣器不叫唤
{
STR_UART_T param;
DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC, 0);// 使能UART时钟,这边0X00指的是用外部的4~24M高速晶振
DrvGPIO_InitFunction(E_FUNC_UART0); // 复用功能引脚设置
param.u32BaudRate = 115200; // 波特率
param.u8cDataBits = DRVUART_DATABITS_8; // 数据位
param.u8cStopBits = DRVUART_STOPBITS_1; // 停止位
param.u8cParity = DRVUART_PARITY_NONE; // 校验位
param.u8cRxTriggerLevel = DRVUART_FIFO_62BYTES; // FIFO存储深度 62字节
param.u8TimeOut = 123; //瞎整的 // FIFO超时设定
DrvUART_Open(UART_PORT0, ¶m); // 串口开启、结构体整体赋值
}
}
void Uart0_test()
{
//---------------------------------------------------------
printf("\n\n"); //具体printf等函数说明,请参看stdio.h
printf("/*==========================\n");
printf(" 菜农新唐M0助学板范例 \n");
printf(" 实验一:串口实验 \n");
printf("leonbaichi 请输入内容 \n");
printf("==========================*/\n");
printf("\n\n");
//------------------------------------------------
//本意是想实现输入什么原样返回
//-----------------------------------------------
}
void UART0Callback(uint32_t data)
{
unsigned int i;
unsigned char ch;
/*---------------华丽的分割线-----------------------------------------------*/
if(UART0->ISR.RLS_INT) //线中断
{
UART0->FSR.BIF =1;
UART0->FSR.PEF =1;
UART0->FSR.FEF =1; //清标志位
}
else
if( UART0->ISR.RDA_INT|UART0->ISR.TOUT_INT) //TOUT或者RDA中断
{
while ((UART0->FSR.RX_EMPTY)) //RX_EMPTY
{//从FIFO中取出全部数据
ch =(unsigned char)( UART0->DATA);//从FIFO中取出1个字符的数据 Uart.RxBuffer[Uart.RxCount ++] = ch;//暂存入缓冲区
}
while (Uart.TxCount != Uart.RxCount)
{
Uart.TxBuffer[Uart.TxCount] = Uart.RxBuffer[Uart.TxCount];//移入发送缓冲区
Uart.TxCount ++;
}
if (!Uart.TxBusy) {//发送器不忙可以立即发送
UART0->DATA = Uart.TxBuffer[Uart.TxdCount++]; //先发送缓冲区中的一个数据
}
}
else
if(UART0->ISR.THRE_INT)
{
UART0->ISR.THRE_IF = UART0->ISR.THRE_IF;//清零
Uart.TxBusy = (Uart.TxCount != Uart.TxdCount);//保证FIFO发送全部结束时,缓冲区空不拒绝发送
for (i = 0; (i < 62) && (Uart.TxCount != Uart.TxdCount); i ++)
{
ch = Uart.TxBuffer[Uart.TxdCount ++];//取出缓冲区1个字节数据
UART0->DATA = ch;//将缓冲区1个字节数据写入FIFO
}
}
}
/*-----------------华丽的分割线--------------------------------------------*/
void UartInit(void)
{
Uart.TxCount = 0;
Uart.RxCount = 0;
Uart.TxdCount = 0;
Uart.RxdCount = 0;
Uart.TxBusy = 0;
DrvUART_EnableInt( UART_PORT0,DRVUART_THREINT,UART0Callback); //调试的时候这个有问题,我不知道该怎么传递这个参数UART0Callback
UART0->IER.THRE_IEN =1; //置位BUFF_ERR ,RLS, THRE, RDA,TOUT
UART0->IER.RLS_IEN=1;
UART0->IER.RDA_IEN=1;
UART0->IER.BUF_ERR_IEN=1;
UART0->IER.TIME_OUT_EN =1; //使能计时
}
int main (void)
{
Sys_Init();
UartInit();
Uart0_test();
while(1);
}
|