打印
[技术问答]

串口发送 总死

[复制链接]
4788|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cub_wolf|  楼主 | 2013-8-19 12:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
void UART_Init1(void)
{
    /* Step 1. GPIO initial */
    P1_MFP &= ~(P13_AIN3_TXD1 | P12_AIN2_RXD1);   
    P1_MFP |= (TXD1 | RXD1);                                                     
                                                                                 

    /* Step 2. Enable and Select UART clock source*/
    UART1_Clock_EN;         //UART Clock Enable, APBCLK[16]:1
    UARTClkSource_ex12MHZ;  //UART Clock is ext12MHz, CLKSEL1[25,24]: 00
    CLKDIV &= ~(15<<8);         //UART Clock DIV Number = 0;

    /* Step 3. Select Operation mode */
    IPRSTC2 |= UART1_RST;   //Reset UART0
    IPRSTC2 &= ~UART1_RST;  //Reset end
    UA1_FCR |= TX_RST;      //Tx FIFO Reset
    UA1_FCR |= RX_RST;      //Rx FIFO Reset
    UA1_FCR |=RFITL_14;

    UA1_LCR |= PBE;             //可以有校验
    UA1_LCR |=EPE;                        //偶校验
   UA1_LCR &= ~WLS;
    UA1_LCR |= WL_8BIT;     //8 bits Data Length
    UA1_LCR &= NSB_ONE;     //1 stop bit

    /* Step 4. Set BaudRate to 115200*/
    UA1_BAUD |= DIV_X_EN;   //Mode2:DIV_X_EN = 1
    UA1_BAUD |= DIV_X_ONE;  //Mode2:DIV_X_ONE =1
   
    /* For XTAL = 12 MHz */
    UA1_BAUD |= ((12000000 / 19200) -2);        //Set BaudRate to 115200;  UART_CLK/(A+2) = 115200, UART_CLK=12MHz

    //中断
       
     UA1_IER        |= (RTO_IEN|TIME_OUT_EN);       
     NVIC_ISER |= UART1_INT;
     UA1_TOR=0xff00ff;
}




void UART1SendByte(uint8 c)   // 发送串口 字节
{
    UA0_THR = (uint8_t) c;                  
    while((UA0_FSR&TX_FULL) != 0);            //数据发送一段时间  就死在这  不知道为什么呢??????????????????         
         
}




void main(void)
{
   //  目标版 系统初始化
   UART_Init1();
   while(1)
   {
        UART1SendByte('A');
   }
       


}
沙发
nhce| | 2013-8-19 14:40 | 只看该作者
看程序,不应该死在那个位置啊,是否确定数据确实发出来了

使用特权

评论回复
板凳
nhce| | 2013-8-19 14:44 | 只看该作者
看你的程序写的好复杂,去官网下个BSP,里面模块程序都写好的,直接调用就可以,自己改也很方便的

使用特权

评论回复
地板
nhce| | 2013-8-19 14:47 | 只看该作者
我的程序如下,供参考
void UART0_Init(void)
{
    /* Set 115200 baudrate according to 50MHz system clock */
    UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_DIV_MODE2(PLL_CLOCK, 115200);
    _UART_SET_DATA_FORMAT(UART0, UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1);

        UART0->FCR = UART_FCR_TFR_Msk | UART_FCR_RFR_Msk;
        UART0->IER = UART_IER_RDA_IEN_Msk;
        NVIC_EnableIRQ(UART0_IRQn);
}
void UART_Tx(uint8_t dat)
{
        while(DEBUG_PORT->FSR & UART_FSR_TX_FULL_Msk);
        DEBUG_PORT->DATA = dat;
}

void UART_TxString(uint8_t *string)
{
        while(*string)
        {
                UART_Tx(*string++);
        }
}
void UART0_IRQHandler(void)
{
        uint8_t uartdata;

        uartdata = DEBUG_PORT->DATA;
...
}

使用特权

评论回复
5
cub_wolf|  楼主 | 2013-8-19 17:04 | 只看该作者
说实话 本人水平太低 看不懂BSP那些东西 只能用寄存器方式 呵呵    发数据发了一阵子就死了   发送时间随机的

使用特权

评论回复
6
cub_wolf|  楼主 | 2013-8-19 17:04 | 只看该作者
基本上几分钟 就死在那里了

使用特权

评论回复
7
mmuuss586| | 2013-8-20 08:42 | 只看该作者
是不是什么标志位没清啊

使用特权

评论回复
8
cub_wolf|  楼主 | 2013-8-20 08:57 | 只看该作者
问题是发一阵子才死

使用特权

评论回复
9
a_ziliu| | 2013-8-20 09:22 | 只看该作者
如果你一直去丟fifo,資料後面的可能會遺失。
你要去檢查fifo full這個flag.

使用特权

评论回复
10
nhce| | 2013-8-20 09:40 | 只看该作者
基本上串口发送函数可以用两种方式来写,第一种:先写数据,之后来判断FIFO是否为空,不为空就while,为空退出
第二种:先判断FIFO是否为满,为满while,不为满继续,然后写数据,退出
第一种方式的效率很低,大部分时间浪费在等FIFO里的仅有的一个数据发出,FIFO等于没用
第二种方式效率高,如果FIFO还可以放数据,那么放完就走,只有FIFO满的时候会等

但看你的发送函数,是先写数据,之后判断FIFO是否为满,这样会有一个问题,如果本来FIFO就满了,你进来就先写了一个数据,FIFO可能就混乱了,所以建议你修改为第二种方式,参考我发的程序

使用特权

评论回复
11
缥缈九哥| | 2013-8-20 12:00 | 只看该作者
cub_wolf 发表于 2013-8-19 17:04
说实话 本人水平太低 看不懂BSP那些东西 只能用寄存器方式 呵呵    发数据发了一阵子就死了   发送时间随机 ...

我没有详细研究寄存器和TRM手册,对寄存器操作的水平很低。我只会用BSP的API模式,我只会抄DEMO。暂时没有办法帮助你。其实新唐的BSP包也有一种是寄存器模式的。但是我也拒绝去看寄存器。你可以先看寄存器模式的BSP包,先跑起来。再考虑修改。如果不参考BSP包。通常写出来的程序经常会错漏百出的。新唐的BSP包和DEMO使用的成功率非常高。我没有遇到过什么大的问题和BUG。建议你也使用。要善于站在巨人的肩膀上吧。最起码你能省去敲打键盘的很多时间。

使用特权

评论回复
12
rejoice818| | 2013-8-22 02:01 | 只看该作者
可以参考我的,完整工程可以看我发的帖,寄存器有寄存器的好,占用flash资源少,编程有一定水平的人写出来的代码效率比库函数的BSP更高,看个人喜好而已。据我所知新唐原厂的研发也有不少用寄存器的。
/****************************************
*函数名称:UartSend
*输    入:pBuf                          发送数据缓冲区
          unNumOfBytes         发送字节总数
*输    出:无
*功    能:串口发送数据
******************************************/
VOID UartSend(UINT8 *pBuf,UINT32 unNumOfBytes)
{
         UINT32 i;

         for(i=0; i<unNumOfBytes; i++)
         {
         UA0_THR = *(pBuf+i);

         while ((UA0_FSR&TX_EMPTY) == 0x00); //检查发送FIFO是否为空         
         }

}

ps:代码出处《ARM Cortex-M0微处理器原理应用与实践》

使用特权

评论回复
13
缥缈九哥| | 2013-8-22 06:34 | 只看该作者
int UART0_init(void)
{
        STR_UART_T sParam;
          
        /* Set UART0 Pin */
        DrvGPIO_InitFunction(E_FUNC_UART0);

        /* Select UART0 Clock Source From 12Mhz*/
        DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC,0);
       

        /* UART0 Setting */
    sParam.u32BaudRate                 = 3000000;
    sParam.u8cDataBits                 = DRVUART_DATABITS_6;
    sParam.u8cStopBits                 = DRVUART_STOPBITS_1;
    sParam.u8cParity                 = DRVUART_PARITY_NONE;
    sParam.u8cRxTriggerLevel= DRVUART_FIFO_1BYTES;

        if(DrvUART_Open(UART_PORT0,&sParam) != E_SUCCESS)
        {
                printf("UART0 open failed\n");
                return FALSE;
        }
        /* Enable Interrupt and install the call back function */
        DrvUART_EnableInt(UART_PORT0, (DRVUART_RLSINT | DRVUART_RDAINT),UART0_INT_HANDLE);
               
        /* Disable Interrupt */
//        DrvUART_DisableInt(UART_PORT0,DRVUART_RLSINT | DRVUART_THREINT | DRVUART_RDAINT);

        return TRUE;
}

void UART0_puts(const char *buf)
{
        while (*buf)
        {
                while(UART0->FSR.TX_FULL == 1);       
                UART0->DATA =(*buf++)&0xff;
        }
}我好像是用这个的。

使用特权

评论回复
14
ceflsh| | 2013-8-22 20:04 | 只看该作者
学习了。顶一下。

使用特权

评论回复
15
feiyu1818| | 2013-10-18 11:01 | 只看该作者
国人都是拿来主义,能用能跑就好,你还非得自己写,牛人啊……

使用特权

评论回复
16
rejoice818| | 2013-10-19 17:12 | 只看该作者
发送函数里面改一下这句:
while((UA0_FSR&TX_FULL) != 0);
改成
while((UA0_FSR&TX_FULL) == 0);
应该就OK

使用特权

评论回复
17
mingjiezhong| | 2013-10-20 07:44 | 只看该作者
从51过来的人都是这个样子的,随着单片机越来越复杂,不改变思维就是自己找罪受

使用特权

评论回复
18
mingjiezhong| | 2013-10-20 07:49 | 只看该作者
另外多一句嘴,一般串口发送是先检测上次有没有发完才发送数据的,楼主是先检测本次有没有发完才退出这个逻辑先不说有没有问题,首先你单片机就阻塞到等待发送那里了,效率也不行,所以说你自己搞要是水平不够还不知道会出什么问题呢,还是用厂家的吧

使用特权

评论回复
19
elec921| | 2013-10-20 19:26 | 只看该作者
一般就是死在while里面了

使用特权

评论回复
20
骗子的片子| | 2013-12-13 17:15 | 只看该作者
逻辑问题,生产的话用厂家的比较好,自己学习多捣鼓捣鼓也不是错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

71

主题

253

帖子

0

粉丝