zl程序教程

您现在的位置是:首页 >  其它

当前栏目

apollo 3 plus 串口1

串口 Plus Apollo
2023-09-14 09:16:38 时间
  • 串口配置结构


//*****************************************************************************
//
// UART configuration options.
//
//*****************************************************************************
typedef struct
{
    //
    // Standard UART options.
    //
    uint32_t ui32BaudRate;
    uint32_t ui32DataBits;
    uint32_t ui32Parity;
    uint32_t ui32StopBits;
    uint32_t ui32FlowControl;

    //
    // Additional options.
    //
    uint32_t ui32FifoLevels;

    //
    // Buffers
    //
    uint8_t *pui8TxBuffer;
    uint32_t ui32TxBufferSize;
    uint8_t *pui8RxBuffer;
    uint32_t ui32RxBufferSize;
}
am_hal_uart_config_t;

串口初时化函数

uint32_t am_hal_uart_initialize(uint32_t ui32Module, void **ppHandle);

  1. 参数uint32_t ui32Module为串口实例序号,0为串口0,1为串口1
  2. 参数 void **ppHandle为中间变量,需要传入一个void*指针做为串口实例操作变量

串口电源控制接口函数

uint32_t am_hal_uart_power_control(void *pHandle, am_hal_sysctrl_power_state_e ePowerState, bool bRetainState);

  1. 参数void *pHandle为串口实例操作变量
  2. 参数am_hal_sysctrl_power_state_e ePowerState为串口工作的电源状态
    
    //*****************************************************************************
    //
    // Definition of Global Power State enumeration
    //
    //*****************************************************************************
    typedef enum
    {
      AM_HAL_SYSCTRL_WAKE,
      AM_HAL_SYSCTRL_NORMALSLEEP,
      AM_HAL_SYSCTRL_DEEPSLEEP
    } am_hal_sysctrl_power_state_e;
    

    3.  参数bool bRetainState:bRetainState is a flag to ask the HAL to save UART registers.
    This function can be used to switch the power to the UART on or off. If \e
     bRetainState is true during a powerdown operation, it will store the UART
    configuration registers to SRAM, so it can restore them on power-up.

串口参数配置函数

uint32_t am_hal_uart_configure(void *pHandle,const am_hal_uart_config_t *psConfig);

  1. 参数void *pHandle为串口实例操作变量
  2. 参数const am_hal_uart_config_t *psConfig指向串口配置信息

串口收发配置结构体

//*****************************************************************************
//
// @brief UART transfer structure.
//
// This structure describes a UART transaction that can be performed by \e
// am_hal_uart_transfer()
//
//*****************************************************************************
typedef struct
{
    //! Determines whether data should be read or written.
    //!
    //! Should be either AM_HAL_UART_WRITE or AM_HAL_UART_READ
    uint32_t ui32Direction;

    //! Pointer to data to be sent, or space to fill with received data.
    uint8_t *pui8Data;

    //! Number of bytes to send or receive.
    uint32_t ui32NumBytes;

    //! Timeout in milliseconds.
    //!
    //! Given a timeout value, the \e am_hal_uart_transfer() function will keep
    //! trying to transfer data until either the number of bytes is satisfied,
    //! or the time runs out. If provided with a value of zero, the transfer
    //! function will only send as much data as it can immediately deal with.
    //! If provided with a timeout value of \e AM_HAL_UART_WAIT_FOREVER, the
    //! function will block until either the final "read" byte is received or
    //! the final "write" byte is placed in the output buffer.
    uint32_t ui32TimeoutMs;

    //! Number of bytes successfully transferred.
    uint32_t *pui32BytesTransferred;
}am_hal_uart_transfer_t;

串口收发函数

uint32_t am_hal_uart_transfer(void *pHandle, const am_hal_uart_transfer_t *pTransfer)

  1. 参数void *pHandle为串口实例操作变量
  2. 参数const am_hal_uart_transfer_t *pTransfer指向读写串口收发接收结构信息变量

以下为串口1每2秒发送数据例程

//*****************************************************************************
//
//! @file hello_world.c
//!
//! @brief A simple "Hello World" example.
//!
//! Purpose: This example prints a "Hello World" message with some device info.
//!
//! Printing takes place over the ITM at 1M Baud.
//!
//
//*****************************************************************************

//*****************************************************************************
//
// Copyright (c) 2019, Ambiq Micro
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// 
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
// 
// Third party software included in this distribution is subject to the
// additional license terms as defined in the /docs/licenses directory.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// This is part of revision v2.3.1-167-ge65d79147 of the AmbiqSuite Development Package.
//
//*****************************************************************************

#include "am_mcu_apollo.h"
#include "am_bsp.h"
#include "am_util.h"
#include "am_bsp_pins.h"
#include "stm_log.h"


#define UART_HCI_BRIDGE                 1
#define MAX_UART_PACKET_SIZE            2048

//*****************************************************************************
//
// Custom data type.
// Note - am_uart_buffer was simply derived from the am_hal_iom_buffer macro.
//
//*****************************************************************************
#define am_uart_buffer(A)                                                   \
union                                                                   \
  {                                                                       \
    uint32_t words[(A + 3) >> 2];                                       \
      uint8_t bytes[A];                                                   \
  }

//*****************************************************************************
//
// Global Variables
//
//*****************************************************************************
uint8_t g_pui8UARTTXBuffer[MAX_UART_PACKET_SIZE];
am_uart_buffer(1000) g_psWriteData;
am_uart_buffer(1000) g_psReadData;

volatile uint32_t g_ui32UARTRxIndex = 0;
volatile bool g_bRxTimeoutFlag = false;
volatile bool g_bCmdProcessedFlag = false;

//*****************************************************************************
//
// Process "special" UART commands.  Format is:
//      'A'     Header
//      'M'
//      'Y'     Command (ASCII '0' - '2')
//       X      Value   (0 - 255)
//       X
//
//*****************************************************************************
void *g_pvBLEHandle;
void *g_pvUART;
uint8_t carrier_wave_mode = 0;

static void cmd_handler(uint8_t *pBuffer, uint32_t len)
{
   
			NRF_LOG_INFO("%s len=%d",pBuffer,len);
		
}



//*****************************************************************************
//
// Interrupt handler for the UART.
//
//*****************************************************************************
#if UART_HCI_BRIDGE == 0
void am_uart_isr(void)
#else
void am_uart1_isr(void)
#endif
{
  uint32_t ui32Status;

  //
  // Read the masked interrupt status from the UART.
  //
  am_hal_uart_interrupt_status_get(g_pvUART, &ui32Status, true);
  am_hal_uart_interrupt_clear(g_pvUART, ui32Status);
  am_hal_uart_interrupt_service(g_pvUART, ui32Status, 0);

  //
  // If there's an RX interrupt, handle it in a way that preserves the
  // timeout interrupt on gaps between packets.
  //
  if (ui32Status & (AM_HAL_UART_INT_RX_TMOUT | AM_HAL_UART_INT_RX))
  {
	
	
    uint32_t ui32BytesRead;
		g_ui32UARTRxIndex = 0;
    am_hal_uart_transfer_t sRead =
    {
      .ui32Direction = AM_HAL_UART_READ,
      .pui8Data = (uint8_t *) &(g_psReadData.bytes[g_ui32UARTRxIndex]),
      .ui32NumBytes = 23,
      .ui32TimeoutMs = 0,
      .pui32BytesTransferred = &ui32BytesRead,
    };

    am_hal_uart_transfer(g_pvUART, &sRead);

    g_ui32UARTRxIndex += ui32BytesRead;
    
    //
    // If there is a TMOUT interrupt, assume we have a compete packet, and
    // send it over SPI.
    //
    if (ui32Status & (AM_HAL_UART_INT_RX_TMOUT))
    {
      NVIC_DisableIRQ((IRQn_Type)(UART0_IRQn + UART_HCI_BRIDGE));
      cmd_handler(g_psReadData.bytes, g_ui32UARTRxIndex);
      g_bRxTimeoutFlag = true;
			
			
			     
    }
  }
}


void sendByteTest(void)
{
	         static uint32_t count=0;
	          count++;
		        uint32_t ui32NumChars = 0;
						NRF_LOG_INFO("Count=%d",count);
						g_psReadData.bytes[0] = count >> 24;
						g_psReadData.bytes[1] = (count >> 16)&0xff;
						g_psReadData.bytes[2] = (count >> 8) & 0xff;
						g_psReadData.bytes[3] = count & 0xff;
						
						am_hal_uart_transfer_t sWrite; 
			
						sWrite.ui32Direction = AM_HAL_UART_WRITE;
						sWrite.pui8Data = g_psReadData.bytes;
						sWrite.ui32NumBytes = 4;
						sWrite.ui32TimeoutMs = 0;
						sWrite.pui32BytesTransferred = &ui32NumChars;
				

//                
//                    //then send the response to UART
            uint32_t err_code = am_hal_uart_transfer(g_pvUART, &sWrite);
						
}




void am_ctimer_isr(void)
{
  
  // Clear TimerA0 Interrupt.
 	
  uint32_t status = am_hal_ctimer_int_status_get(true);
	
  am_hal_ctimer_int_clear(status);
  am_hal_ctimer_int_service(status);
  
}


void timer0_handler(void)
{
 
	 sendByteTest();
}


void init_ctime0(void)
{

   
  am_hal_ctimer_config_single(0, AM_HAL_CTIMER_TIMERA,
                              AM_HAL_CTIMER_LFRC_32HZ |
                                AM_HAL_CTIMER_FN_REPEAT |
                                 AM_HAL_CTIMER_INT_ENABLE);

	
  am_hal_ctimer_int_enable(AM_HAL_CTIMER_INT_TIMERA0C0);

  am_hal_ctimer_period_set(0, AM_HAL_CTIMER_TIMERA, 64, 0);

  am_hal_ctimer_int_register(AM_HAL_CTIMER_INT_TIMERA0C0,timer0_handler);
  
  // Start the timer.
  am_hal_ctimer_start(0, AM_HAL_CTIMER_TIMERA);

   NVIC_EnableIRQ(CTIMER_IRQn);
   am_hal_interrupt_master_enable();
}	


//*****************************************************************************
//
// Main
//
//*****************************************************************************
int
main(void)
{
	
    am_util_id_t sIdDevice;
    uint32_t ui32StrBuf;
    //
    // Set the clock frequency.
    //
    am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);

    //
    // Set the default cache configuration
    //
    am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
    am_hal_cachectrl_enable();

    //
    // Configure the board for low power operation.
    //
    am_bsp_low_power_init();

    //
    // Initialize the printf interface for ITM output
    //
		  
    
    am_bsp_itm_printf_enable();

    //
    // Print the banner.
    //
    am_util_stdio_terminal_clear();
    am_util_stdio_printf("Hello World!\n\n");

    //
    // Print the device info.
    //
    am_util_id_device(&sIdDevice);
    am_util_stdio_printf("Vendor Name: %s\n", sIdDevice.pui8VendorName);
    am_util_stdio_printf("Device type: %s\n", sIdDevice.pui8DeviceName);


    am_util_stdio_printf("Qualified: %s\n",
                         sIdDevice.sMcuCtrlDevice.ui32Qualified ?
                         "Yes" : "No");

    am_util_stdio_printf("Device Info:\n"
                         "\tPart number: 0x%08X\n"
                         "\tChip ID0:    0x%08X\n"
                         "\tChip ID1:    0x%08X\n"
                         "\tRevision:    0x%08X (Rev%c%c)\n",
                         sIdDevice.sMcuCtrlDevice.ui32ChipPN,
                         sIdDevice.sMcuCtrlDevice.ui32ChipID0,
                         sIdDevice.sMcuCtrlDevice.ui32ChipID1,
                         sIdDevice.sMcuCtrlDevice.ui32ChipRev,
                         sIdDevice.ui8ChipRevMaj, sIdDevice.ui8ChipRevMin );

    //
    // If not a multiple of 1024 bytes, append a plus sign to the KB.
    //
    ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32FlashSize % 1024 ) ? '+' : 0;
    am_util_stdio_printf("\tFlash size:  %7d (%d KB%s)\n",
                         sIdDevice.sMcuCtrlDevice.ui32FlashSize,
                         sIdDevice.sMcuCtrlDevice.ui32FlashSize / 1024,
                         &ui32StrBuf);

    ui32StrBuf = ( sIdDevice.sMcuCtrlDevice.ui32SRAMSize % 1024 ) ? '+' : 0;
    am_util_stdio_printf("\tSRAM size:   %7d (%d KB%s)\n\n",
                         sIdDevice.sMcuCtrlDevice.ui32SRAMSize,
                         sIdDevice.sMcuCtrlDevice.ui32SRAMSize / 1024,
                         &ui32StrBuf);
    //
    // Print the compiler version.
    //
    am_util_stdio_printf("App Compiler:    %s\n", COMPILER_VERSION);
#if defined(AM_PART_APOLLO3)  || defined(AM_PART_APOLLO3P)
    am_util_stdio_printf("HAL Compiler:    %s\n", g_ui8HALcompiler);
    am_util_stdio_printf("HAL SDK version: %d.%d.%d\n",
                         g_ui32HALversion.s.Major,
                         g_ui32HALversion.s.Minor,
                         g_ui32HALversion.s.Revision);
    am_util_stdio_printf("HAL compiled with %s-style registers\n",
                         g_ui32HALversion.s.bAMREGS ? "AM_REG" : "CMSIS");

    am_hal_security_info_t secInfo;
    char sINFO[32];
    uint32_t ui32Status;
    ui32Status = am_hal_security_get_info(&secInfo);
    if (ui32Status == AM_HAL_STATUS_SUCCESS)
    {
        if ( secInfo.bInfo0Valid )
        {
            am_util_stdio_sprintf(sINFO, "INFO0 valid, ver 0x%X", secInfo.info0Version);
        }
        else
        {
            am_util_stdio_sprintf(sINFO, "INFO0 invalid");
        }

        am_util_stdio_printf("SBL ver: 0x%x - 0x%x, %s\n",
            secInfo.sblVersion, secInfo.sblVersionAddInfo, sINFO);
    }
    else
    {
        am_util_stdio_printf("am_hal_security_get_info failed 0x%X\n", ui32Status);
    }
#endif // AM_PART_APOLLO3


//		am_hal_gpio_pincfg_t g_pin10_gpio =
//		{
//				.uFuncSel            = AM_HAL_PIN_10_GPIO,
//			  .ePullup = AM_HAL_GPIO_PIN_PULLUP_NONE,
//				.eDriveStrength      = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA,
//				.eGPOutcfg           = AM_HAL_GPIO_PIN_OUTCFG_PUSHPULL,
//			  .ePowerSw  = AM_HAL_GPIO_PIN_POWERSW_NONE 
//		};
//    am_hal_gpio_pinconfig(10,g_pin10_gpio);
//		for(uint8_t i=0; i<10;i++)
//		{
//			am_hal_gpio_output_toggle(10);
//			am_util_delay_ms(200);
//		}
//		
//	
//		uint32_t portValue;
//		uint32_t res = am_hal_gpio_state_read(16,AM_HAL_GPIO_INPUT_READ,&portValue);
//		am_util_stdio_printf("port is %d,res=%d\r\n",portValue,res);
//		
//		
		
		
		
    //
    // We are done printing.
    // Disable debug printf messages on ITM.
    //
 //   am_bsp_debug_printf_disable();

			
//		am_hal_gpio_pincfg_t g_pin16_gpio_int =
//		{
//				.uFuncSel            = AM_HAL_PIN_16_GPIO,
//			  .ePullup = AM_HAL_GPIO_PIN_PULLUP_WEAK,
//				.eDriveStrength      = AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA,
//				.eGPOutcfg           = AM_HAL_GPIO_PIN_OUTCFG_DISABLE,
//			  .eGPInput = AM_HAL_GPIO_PIN_INPUT_ENABLE,
//			  .eIntDir = AM_HAL_GPIO_PIN_INTDIR_BOTH
//		};
//		
//		am_hal_gpio_pinconfig(16,g_pin16_gpio_int); 
//		
//		AM_HAL_GPIO_MASKCREATE(GpioIntMask);
//    am_hal_gpio_interrupt_clear(AM_HAL_GPIO_MASKBIT(pGpioIntMask, 16));
//		am_hal_gpio_interrupt_register(16,io16_int_handler);
//     
//		am_hal_gpio_interrupt_enable(AM_HAL_GPIO_MASKBIT(pGpioIntMask, 16));
//		NVIC_EnableIRQ(GPIO_IRQn);

		RTT_INIT();
	  NRF_LOG_INFO("main is started\n");
    
     //
    // Start the UART.
    //
    am_hal_uart_config_t sUartConfig =
    {
        //
        // Standard UART settings: 115200-8-N-1
        //
        .ui32BaudRate    = 115200,
        .ui32DataBits    = AM_HAL_UART_DATA_BITS_8,
        .ui32Parity      = AM_HAL_UART_PARITY_NONE,
        .ui32StopBits    = AM_HAL_UART_ONE_STOP_BIT,
        .ui32FlowControl = AM_HAL_UART_FLOW_CTRL_NONE,

        //
        // Set TX and RX FIFOs to interrupt at three-quarters full.
        //
        .ui32FifoLevels = (AM_HAL_UART_TX_FIFO_3_4 |
                           AM_HAL_UART_RX_FIFO_3_4),

        //
        // This code will use the standard interrupt handling for UART TX, but
        // we will have a custom routine for UART RX.
        //
        .pui8TxBuffer = g_pui8UARTTXBuffer,
        .ui32TxBufferSize = sizeof(g_pui8UARTTXBuffer),
        .pui8RxBuffer = 0,
        .ui32RxBufferSize = 0,
    };

    am_hal_uart_initialize(UART_HCI_BRIDGE, &g_pvUART);
    am_hal_uart_power_control(g_pvUART, AM_HAL_SYSCTRL_WAKE, false);
    am_hal_uart_configure(g_pvUART, &sUartConfig);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_UART_TX,g_AM_BSP_GPIO_UART_TX);
    am_hal_gpio_pinconfig(AM_BSP_GPIO_UART_RX,g_AM_BSP_GPIO_UART_RX);
    
    //
    // Make sure to enable the interrupts for RX, since the HAL doesn't already
    // know we intend to use them.
    //
    NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + UART_HCI_BRIDGE));
    am_hal_uart_interrupt_enable(g_pvUART, (AM_HAL_UART_INT_RX |
                                 AM_HAL_UART_INT_RX_TMOUT

		                             ));

    am_hal_interrupt_master_enable();

     uint32_t ui32NumChars;
		
		init_ctime0();
		
    //
    // Loop forever while sleeping.
    //
    while (1)
    {
			 
			  if (g_bRxTimeoutFlag)
        {
            //
            // If we have incoming UART traffic, the interrupt handler will
            // read it out for us, but we will need to echo it back out to the
            // radio manually.
            //

            g_ui32UARTRxIndex = 0;
            g_bRxTimeoutFlag = false;
            
					
					
						NVIC_EnableIRQ((IRQn_Type)(UART0_IRQn + UART_HCI_BRIDGE));
        }
				
        //
        // Go to Deep Sleep.
        //
//        am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
		
    }
}