nu-lb-nuc140 freertos 串口 通信

22 篇文章 0 订阅

参考例子:
Nu_LB_NUC140_BSP\ThirdParty\FreeRTOS\Demo\CORTEX_STM32F103_Keil
FreeRTOS_Serial

参考链接:
https://blog.csdn.net/wowocpp/article/details/81982665

1 串口硬件:

这里写图片描述

这里写图片描述

这里写图片描述

2 功能简介

UART1 间隔一定的时间 发送 ABCDEFGHIJKLMNOPQRSTUVWX 字符串,共24个字节
同时 UART1 准备接收 ABCDEFGHIJKLMNOPQRSTUVWX 字符串,如果字符串不对,会报错。

系统的log 信息,是通过 UART0 打印的。

3 代码

//
// GPIO_LED : GPIO output to control an on-board red LED
// 
// EVB : Nu-LB-NUC140
// MCU : NUC140VE3CN

// low-active output control by GPC12

#include <stdio.h>
#include "NUC100Series.h"
#include "MCU_init.h"
#include "SYS_init.h"

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"

/* The queue used to hold received characters. */
static QueueHandle_t xRxedChars;
static QueueHandle_t xCharsForTx;

static void vComTxTask( void *pvParameters );

static void vComRxTask( void *pvParameters );


void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
{
    unsigned short usBit;

    vTaskSuspendAll();

    if(uxLED == 0){

        GPIO_TOGGLE(PC12);
    }

    if(uxLED == 1){

        GPIO_TOGGLE(PC14);
    }

    xTaskResumeAll();
}

void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
{
    unsigned short usBit;

    vTaskSuspendAll();



    if(uxLED == 0){

        if( xValue == pdFALSE ){

            PC12 = 1 ; // off

        }else{

            PC12 = 0 ; // on
        }

    }

    if(uxLED == 1){

        if( xValue == pdFALSE ){

            PC14 = 1 ;

        }else{

            PC14 = 0 ;
        }

    }

    xTaskResumeAll();
}


signed portBASE_TYPE xSerialPutChar(signed char cOutChar, TickType_t xBlockTime )
{
signed portBASE_TYPE xReturn;

    if( xQueueSend( xCharsForTx, &cOutChar, xBlockTime ) == pdPASS )
    {
        xReturn = pdPASS;

        UART_ENABLE_INT(UART1,UART_IER_THRE_IEN_Msk);
    }
    else
    {
        xReturn = pdFAIL;
    }

    return xReturn;
}


static void vComTxTask( void *pvParameters )
{
    char cByteToSend;
    TickType_t xTimeToWait;

    for( ;; )
    {
        for( cByteToSend = 'A'; cByteToSend <= 'X'; cByteToSend++ )
        {
            if( xSerialPutChar(cByteToSend, 0 ) == pdPASS )
            {
                vParTestToggleLED( 0 );
            }
        }   


        vParTestSetLED( 0, pdFALSE );

        xTimeToWait = xTaskGetTickCount() + 3;

        /* Make sure we don't wait too long... */
        xTimeToWait %= 0x96;

        /* ...but we do want to wait. */
        if( xTimeToWait < 0x32 )
        {
            xTimeToWait = 0x32;
        }

        vTaskDelay( xTimeToWait );      

    }   

} 



signed portBASE_TYPE xSerialGetChar(signed char *pcRxedChar, TickType_t xBlockTime )
{

    /* Get the next character from the buffer.  Return false if no characters
    are available, or arrive before xBlockTime expires. */
    if( xQueueReceive( xRxedChars, pcRxedChar, xBlockTime ) )
    {
        return pdTRUE;
    }
    else
    {
        return pdFALSE;
    }
}


/* Check variable used to ensure no error have occurred.  The Rx task will
increment this variable after every successfully received sequence.  If at any
time the sequence is incorrect the the variable will stop being incremented. */
static volatile UBaseType_t uxRxLoops = 0;

static void vComRxTask( void *pvParameters )
{
    signed char cExpectedByte, cByteRxed;
    BaseType_t xResyncRequired = pdFALSE, xErrorOccurred = pdFALSE;


    for( ;; )
    {
        /* We expect to receive the characters from comFIRST_BYTE to
        comLAST_BYTE in an incrementing order.  Loop to receive each byte. */
        for( cExpectedByte = 'A'; cExpectedByte <= 'X'; cExpectedByte++ )
        {
            /* Block on the queue that contains received bytes until a byte is
            available. */
            if( xSerialGetChar(&cByteRxed, ( ( TickType_t ) 0xffff ) ) )
            {
                /* Was this the byte we were expecting?  If so, toggle the LED,
                otherwise we are out on sync and should break out of the loop
                until the expected character sequence is about to restart. */

                printf("%c",cByteRxed);
                if( cByteRxed == cExpectedByte )
                {
                    vParTestToggleLED( 1);
                }
                else
                {
                    xResyncRequired = pdTRUE;
                    break; /*lint !e960 Non-switch break allowed. */
                }
            }
        }

        /* Turn the LED off while we are not doing anything. */
        vParTestSetLED( 1, pdFALSE );

        /* Did we break out of the loop because the characters were received in
        an unexpected order?  If so wait here until the character sequence is
        about to restart. */
        if( xResyncRequired == pdTRUE )
        {

            printf(" vComRxTask Error\r\n");
            while( cByteRxed != 'X' )
            {
                /* Block until the next char is available. */
                xSerialGetChar(&cByteRxed, ( TickType_t ) 0xffff  );
            }
            printf("Err22--0x%x\r\n",cByteRxed);
            /* Note that an error occurred which caused us to have to resync.
            We use this to stop incrementing the loop counter so
            sAreComTestTasksStillRunning() will return false - indicating an
            error. */
            xErrorOccurred++;

            /* We have now resynced with the Tx task and can continue. */
            xResyncRequired = pdFALSE;
        }
        else
        {
            if( xErrorOccurred < 6 )
            {
                /* Increment the count of successful loops.  As error
                occurring (i.e. an unexpected character being received) will
                prevent this counter being incremented for the rest of the
                execution.   Don't worry about mutual exclusion on this
                variable - it doesn't really matter as we just want it
                to change. */
                uxRxLoops++;
            }
        }
    }
} 




void vStartThreadTasks( void )
{   
        /* Initialise the com port then spawn the Rx and Tx tasks. */   
        /* Create the queues used to hold Rx/Tx characters. */
    xRxedChars = xQueueCreate( 26, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
    xCharsForTx = xQueueCreate( 26, ( unsigned portBASE_TYPE ) sizeof( signed char ) );

    /* The Tx task is spawned with a lower priority than the Rx task. */
    xTaskCreate( vComTxTask, "COMTx", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY , ( TaskHandle_t * ) NULL );
    xTaskCreate( vComRxTask, "COMRx", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, ( TaskHandle_t * ) NULL );

}




void UART1_IRQHandler(void)
{

    portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

    char cChar; 

    uint8_t in_char;

    if(UART_IS_RX_READY(UART1)) {       

        cChar = UART_READ(UART1);
        //printf("%c",cChar);
        xQueueSendFromISR( xRxedChars, &cChar, &xHigherPriorityTaskWoken );

    }

    if(UART_IS_TX_EMPTY(UART1)){

        /* The interrupt was caused by the THR becoming empty.  Are there any
        more characters to transmit? */
        if( xQueueReceiveFromISR( xCharsForTx, &cChar, &xHigherPriorityTaskWoken ) == pdTRUE )
        {
            /* A character was retrieved from the queue so can be sent to the
            THR now. */         
            UART_WRITE(UART1, cChar);
        }
        else
        {
            UART_DISABLE_INT(UART1,UART_IER_THRE_IEN_Msk);          
        }       
    }

    portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

}



int main(void)
{
    SYS_Init();      
        UART_Open(UART0, 115200);
        printf("Hello World \r\n"); 

        GPIO_SetMode(PC, BIT12, GPIO_MODE_OUTPUT);

        GPIO_SetMode(PC, BIT14, GPIO_MODE_OUTPUT);

        UART_Open(UART1,115200);  // enable UART1 at 115200 baudrate
    UART_ENABLE_INT(UART1, UART_IER_RDA_IE_Msk);
    NVIC_EnableIRQ(UART1_IRQn);

      vStartThreadTasks();

    vTaskStartScheduler();

    while(1);

}

5 主要研究的地方

队列
队列大小
队列接收和发送操作是原子操作吗

E:\Nu_LB_Nuc140\Nu_LB_NUC140_BSP\SampleCode\Nu-LB-NUC140\FreeRTOS_Serial

(稍后补充)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值