功能1 :1秒钟数据包"Hello World!"(没配置阻塞读写)
功能2 :接收啥发送啥(需要特殊的配置,个人理解,有点阻塞的读写方式,但是好像又不是标准的阻塞读写)
原理:简单就是将自定义的FIFO缓存区,读/写到ASCLIN内置的16位FIFO即可。
这里借助串口的中断发送/接收依然可以理解为:和51 32一样,每一位的发送/接收,触发一个中断,(虽然中断函数是调用一个iLLd封装的一个发送/接收函数完成的,让人觉得,好像触发一次中断,调用函数直接一次发送/接收,实际不是的),另外ASCLIN内部有16位的FIFO,然后用户这边定义是64位FIFO,接收/发送中断函数的调用就是,把64位FIFO,写入ASCLIN的16位FIFO,或者读ASCLIN16位FIFO到用户64位FIFO。然后16位的FIFO自动进行收发,这俩算法实现,官方提供的iLLD库以实现,只需要串口发送/接收中断调用即可。
以及功能2发送采用标准的接口配置,否则收到后发送,就会卡死,甚至程序崩溃。
实测是每一位都要触发中断:
主要用到iLLD库里的:
#include "IfxAsclin_Asc.h"
#include "IfxCpu_Irq.h"
#include "Bsp.h" //waitTime
这里注意,
#define UART_PIN_RX IfxAsclin2_RXE_P33_8_IN /* UART receive port pin */
#define UART_PIN_TX IfxAsclin2_TX_P33_9_OUT /* UART transmit port pin */
IfxAsclin_Rx_In IfxAsclin2_RXE_P33_8_IN = {&MODULE_ASCLIN2, {&MODULE_P33, 8}, Ifx_RxSel_e};
IfxAsclin_Tx_Out IfxAsclin2_TX_P33_9_OUT = {&MODULE_ASCLIN2, {&MODULE_P33, 9}, IfxPort_OutputIdx_alt2};
这里ASCLIN外设模块,还是以&MODULE开头的,只不过是用了宏定义的方式层层包含关系,在#include "IfxAsclin_PinMap.h"里面有定义,本质用到的还是io口作为RX/TX引脚:&MODULE_P33
延时函数使用方法,回看LED章节
/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "IfxAsclin_Asc.h"
#include "IfxCpu_Irq.h"
#include "Bsp.h"
/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define UART_BAUDRATE 460800 /* UART baud rate in bit/s */
#define UART_PIN_RX IfxAsclin2_RXE_P33_8_IN /* UART receive port pin */
#define UART_PIN_TX IfxAsclin2_TX_P33_9_OUT /* UART transmit port pin */
/* Definition of the interrupt priorities */
#define INTPRIO_ASCLIN2_RX 18
#define INTPRIO_ASCLIN2_TX 19
#define UART_RX_BUFFER_SIZE 64 /* Definition of the receive buffer size */
#define UART_TX_BUFFER_SIZE 64 /* Definition of the transmit buffer size */
/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
/* Declaration of the ASC handle */
static IfxAsclin_Asc g_ascHandle;
/* Declaration of the FIFOs parameters */
static uint8 g_ascTxBuffer[UART_TX_BUFFER_SIZE];
static uint8 g_ascRxBuffer[UART_RX_BUFFER_SIZE];
/* Definition of txData and rxData */
uint8 g_txData[] = "Hello World!";
/* Size of the message */
Ifx_SizeT g_count = sizeof(g_txData)-1;
/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
/* Adding of the interrupt service routines */
IFX_INTERRUPT(asclin1TxISR, 0, INTPRIO_ASCLIN2_TX);
void asclin1TxISR(void)
{
IfxAsclin_Asc_isrTransmit(&g_ascHandle);
}
IFX_INTERRUPT(asclin1RxISR, 0, INTPRIO_ASCLIN2_RX);
void asclin1RxISR(void)
{
IfxAsclin_Asc_isrReceive(&g_ascHandle);
}
/* This function initializes the ASCLIN UART module */
void init_ASCLIN_UART(void)
{
/* Initialize an instance of IfxAsclin_Asc_Config with default values */
IfxAsclin_Asc_Config ascConfig;
IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN2);
/* Set the desired baud rate */
ascConfig.baudrate.baudrate = UART_BAUDRATE;
/* ISR priorities and interrupt target */
ascConfig.interrupt.txPriority = INTPRIO_ASCLIN2_TX;
ascConfig.interrupt.rxPriority = INTPRIO_ASCLIN2_RX;
ascConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex());// 跳转进去可以发现这个参数可以用IfxSrc_Tos_cpu0代替
/* FIFO configuration */
ascConfig.txBuffer = &g_ascTxBuffer;
ascConfig.txBufferSize = UART_TX_BUFFER_SIZE;
ascConfig.rxBuffer = &g_ascRxBuffer;
ascConfig.rxBufferSize = UART_RX_BUFFER_SIZE;
/* Pin configuration */
const IfxAsclin_Asc_Pins pins =
{
NULL_PTR, IfxPort_InputMode_pullUp, /* CTS pin not used */
&UART_PIN_RX, IfxPort_InputMode_pullUp, /* RX pin */
NULL_PTR, IfxPort_OutputMode_pushPull, /* RTS pin not used */
&UART_PIN_TX, IfxPort_OutputMode_pushPull, /* TX pin */
IfxPort_PadDriver_cmosAutomotiveSpeed1
};
ascConfig.pins = &pins;
IfxAsclin_Asc_initModule(&g_ascHandle, &ascConfig); /* Initialize module with above parameters */
}
/* This function sends and receives the string "Hello World!" */
void send_receive_ASCLIN_UART_message(void)
{
IfxAsclin_Asc_write(&g_ascHandle, g_txData, &g_count, TIME_INFINITE); /* Transmit data via TX */
waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, 1000));
}
开启了接收/发送中断
接收优先级是18 发送优先级19 缓冲FIFO是64字节
设置比特率:460800
/* Declaration of the ASC handle */
static IfxAsclin_Asc g_ascHandle;
这个就相当于Linux设备句柄,以后操作这个ASCLIN的uart模块,直接用这个句柄即可;
比如发送接收,都是直接使用这个句柄:
IfxAsclin_Asc_isrTransmit(&g_ascHandle);
IfxAsclin_Asc_isrReceive(&g_ascHandle);
1.定义一个初始化ASCLIN配置的结构体,并初始化为默认参数:
/* Initialize an instance of IfxAsclin_Asc_Config with default values */
IfxAsclin_Asc_Config ascConfig;
IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN2);
2.默认参数不符合需求,单拎出来修改对应的参数,比如设置波特率,中断优先级,以及设置cpu0处理中断,接收发送的FIFO缓存区,RX/TX引脚,硬件流引脚(CTX/RTS引脚)等:
/* Set the desired baud rate */
ascConfig.baudrate.baudrate = UART_BAUDRATE;
/* ISR priorities and interrupt target */
ascConfig.interrupt.txPriority = INTPRIO_ASCLIN2_TX;
ascConfig.interrupt.rxPriority = INTPRIO_ASCLIN2_RX;
ascConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex()); // IfxSrc_Tos_cpu0
/* FIFO configuration */
ascConfig.txBuffer = &g_ascTxBuffer;
ascConfig.txBufferSize = UART_TX_BUFFER_SIZE;
ascConfig.rxBuffer = &g_ascRxBuffer;
ascConfig.rxBufferSize = UART_RX_BUFFER_SIZE;
/* Pin configuration */
const IfxAsclin_Asc_Pins pins =
{
NULL_PTR, IfxPort_InputMode_pullUp, /* CTS pin not used */
&UART_PIN_RX, IfxPort_InputMode_pullUp, /* RX pin */
NULL_PTR, IfxPort_OutputMode_pushPull, /* RTS pin not used */
&UART_PIN_TX, IfxPort_OutputMode_pushPull, /* TX pin */
IfxPort_PadDriver_cmosAutomotiveSpeed1
};
ascConfig.pins = &pins;
3.最后调用函数,初始化:
IfxAsclin_Asc_initModule(&g_ascHandle, &ascConfig); /* Initialize module with above parameters */
4.编写中断服务函数
/* Adding of the interrupt service routines */
IFX_INTERRUPT(asclin1TxISR, 0, INTPRIO_ASCLIN2_TX);
void asclin1TxISR(void)
{
IfxAsclin_Asc_isrTransmit(&g_ascHandle);
}
IFX_INTERRUPT(asclin1RxISR, 0, INTPRIO_ASCLIN2_RX);
void asclin1RxISR(void)
{
IfxAsclin_Asc_isrReceive(&g_ascHandle);
}
5.调用系统的读写
/* This function sends and receives the string "Hello World!" */
void send_receive_ASCLIN_UART_message(void)
{
IfxAsclin_Asc_write(&g_ascHandle, g_txData, &g_count, TIME_INFINITE); /* Transmit data via TX */
// IfxAsclin_Asc_read(&g_ascHandle, rx_data, &readCount, TIME_INFINITE);
waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, 1000)); //延时1000ms
}
1.
在初始化ASCLIN的串口配置的时候,调用了IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN2);这个函数对配置参数结构体配置了,然后默认参数不一定是我们要的配置,所有在需要根据配置做相应的修改,或者直接跳转进去,把默认参数改掉。
这里实测,串口默认过采样因子需要改成16,以及采样点设置为8.
config->baudrate.oversampling = IfxAsclin_OversamplingFactor_16; /* default oversampling factor*/
config->bitTiming.samplePointPosition = IfxAsclin_SamplePointPosition_8; /* sample point position at 8*/
简单粗暴理解,就是过采样因子,就是一个波特率的bit位分为16段,采样点,就是分的16段,第8段,硬件会根据设置的采样点个数,例如代码中的:
config->bitTiming.medianFilter = IfxAsclin_SamplesPerBit_one; /* one sample per bit*/
选择一个(或者多个,取决于你的设置)最佳采样点。
其他的什么8位数据位,1位停止位,无奇偶校验等设置默认即可。
2.
中断服务函数写法,有固定的格式,同上一篇文件,格式固定。
IFX_INTERRUPT(函数名字, 0, 中断优先级);
void 函数名字(void)
{
}
#ifndef ASCLIN_UART_H_
#define ASCLIN_UART_H_
void init_ASCLIN_UART(void); /* Initialization function */
void send_receive_ASCLIN_UART_message(void); /* Send and receive function */
#endif /* ASCLIN_UART_H_ */
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "Blinky_LED.h"
#include "interrupt.h"
#include "UART_ASC.h"
IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;
void core0_main(void)
{
IfxCpu_enableInterrupts();
/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
* Enable the watchdogs and service them periodically if it is required
*/
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
/* Wait for CPU sync event */
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
IfxCpu_enableInterrupts();
initLED(); //LED初始化
initGtmTom(); //定时器初始化
init_ASCLIN_UART(); // ASCLIN串口初始化
while(1)
{
send_receive_ASCLIN_UART_message(); // 1s心跳包
}
}
这个读写,功能需要特殊配置(即初始化标准接口配置),这里读写有点阻塞读写那个味道,但是把好像又不是,暂时理解为阻塞的读写方式。
就是在原有的功能1的基础上添加:
static IfxStdIf_DPipe g_ascStandardInterface; /* Standard interface object */
/* Initialize the Standard Interface */
IfxAsclin_Asc_stdIfDPipeInit(&g_ascStandardInterface, &g_ascHandle);
/* Initialize the Console */
Ifx_Console_init(&g_ascStandardInterface);
完整的如下:
/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "IfxAsclin_Asc.h"
#include "IfxCpu_Irq.h"
#include "Bsp.h"
#include "Ifx_Console.h"
/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define UART_BAUDRATE 460800 /* UART baud rate in bit/s */
#define UART_PIN_RX IfxAsclin2_RXE_P33_8_IN /* UART receive port pin */
#define UART_PIN_TX IfxAsclin2_TX_P33_9_OUT /* UART transmit port pin */
/* Definition of the interrupt priorities */
#define INTPRIO_ASCLIN2_RX 18
#define INTPRIO_ASCLIN2_TX 19
#define UART_RX_BUFFER_SIZE 64 /* Definition of the receive buffer size */
#define UART_TX_BUFFER_SIZE 64 /* Definition of the transmit buffer size */
/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
/* Declaration of the ASC handle */
static IfxAsclin_Asc g_ascHandle;
static IfxStdIf_DPipe g_ascStandardInterface; /* Standard interface object */
/* Declaration of the FIFOs parameters */
static uint8 g_ascTxBuffer[UART_TX_BUFFER_SIZE];
static uint8 g_ascRxBuffer[UART_RX_BUFFER_SIZE];
/* Definition of txData and rxData */
uint8 g_txData[] = "Hello World!";
/* Size of the message */
Ifx_SizeT g_count = sizeof(g_txData)-1;
/*********************************************************************************************************************/
/*---------------------------------------------Function Implementations----------------------------------------------*/
/*********************************************************************************************************************/
uint16 tcnt =0 ;
uint16 rcnt = 0;
/* Adding of the interrupt service routines */
IFX_INTERRUPT(asclin1TxISR, 0, INTPRIO_ASCLIN2_TX);
void asclin1TxISR(void)
{
tcnt++;
IfxAsclin_Asc_isrTransmit(&g_ascHandle);
}
IFX_INTERRUPT(asclin1RxISR, 0, INTPRIO_ASCLIN2_RX);
void asclin1RxISR(void)
{
rcnt++;
IfxAsclin_Asc_isrReceive(&g_ascHandle);
}
/* This function initializes the ASCLIN UART module */
void init_ASCLIN_UART(void)
{
/* Initialize an instance of IfxAsclin_Asc_Config with default values */
IfxAsclin_Asc_Config ascConfig;
IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN2);
/* Set the desired baud rate */
ascConfig.baudrate.baudrate = UART_BAUDRATE;
/* ISR priorities and interrupt target */
ascConfig.interrupt.txPriority = INTPRIO_ASCLIN2_TX;
ascConfig.interrupt.rxPriority = INTPRIO_ASCLIN2_RX;
ascConfig.interrupt.typeOfService = IfxCpu_Irq_getTos(IfxCpu_getCoreIndex()); // IfxSrc_Tos_cpu0
/* FIFO configuration */
ascConfig.txBuffer = &g_ascTxBuffer;
ascConfig.txBufferSize = UART_TX_BUFFER_SIZE;
ascConfig.rxBuffer = &g_ascRxBuffer;
ascConfig.rxBufferSize = UART_RX_BUFFER_SIZE;
/* Pin configuration */
const IfxAsclin_Asc_Pins pins =
{
NULL_PTR, IfxPort_InputMode_pullUp, /* CTS pin not used */
&UART_PIN_RX, IfxPort_InputMode_pullUp, /* RX pin */
NULL_PTR, IfxPort_OutputMode_pushPull, /* RTS pin not used */
&UART_PIN_TX, IfxPort_OutputMode_pushPull, /* TX pin */
IfxPort_PadDriver_cmosAutomotiveSpeed1
};
ascConfig.pins = &pins;
IfxAsclin_Asc_initModule(&g_ascHandle, &ascConfig); /* Initialize module with above parameters */
/* Initialize the Standard Interface */
IfxAsclin_Asc_stdIfDPipeInit(&g_ascStandardInterface, &g_ascHandle);
/* Initialize the Console */
Ifx_Console_init(&g_ascStandardInterface);
}
/* This function sends and receives the string "Hello World!" */
void send_receive_ASCLIN_UART_message(void)
{
IfxAsclin_Asc_write(&g_ascHandle, g_txData, &g_count, TIME_INFINITE); /* Transmit data via TX */
waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, 1000));
}
void read2send(void)
{
Ifx_SizeT count ;
uint8 data[128] ;
uint8 rx_data; //方法三要用
//方法1--简单好似阻塞读写 --需要配置标准接口(如果不配置,多次后会程序崩溃)
count = (Ifx_SizeT)IfxAsclin_Asc_getReadCount(&g_ascHandle);
IfxAsclin_Asc_read(&g_ascHandle, (void *)data, &count, TIME_INFINITE);
IfxAsclin_Asc_write(&g_ascHandle,(void *)data, &count, TIME_INFINITE);
//方法2 强制等待根据fifo状态进行阻塞读写(也需要标准接口配置如果不配置,多次后会程序崩溃)
/*
count = (Ifx_SizeT)IfxAsclin_Asc_getReadCount(&g_ascHandle);
while (IfxAsclin_Asc_read(&g_ascHandle, &data, &count, TIME_INFINITE) != TRUE);
while(IfxAsclin_getRxFifoFillLevel(g_ascHandle.asclin) != 0); //双重确认读完成
IfxAsclin_Asc_write(&g_ascHandle,data, &count, TIME_INFINITE);
while(IfxAsclin_getTxFifoFillLevel(g_ascHandle.asclin) != 0);
*/
//方法3 读一个写一个 -- 不需要初始化标准接口
/*
while(count != 0 ){
rx_data= IfxAsclin_Asc_blockingRead(&g_ascHandle);
IfxAsclin_Asc_blockingWrite(&g_ascHandle, rx_data);
}
*/
}
这里初始化配置和功能1一致,添加了标准接口配置初始化(类似于重映射Uart输出道printf那种)
提供的函数在:#include "Ifx_Console.h"里面
/* Initialize the Standard Interface */
IfxAsclin_Asc_stdIfDPipeInit(&g_ascStandardInterface, &g_ascHandle);
/* Initialize the Console */
Ifx_Console_init(&g_ascStandardInterface);
配置了标准接口,iLLD库提供了标准接口的接收/发送函数(没实测),以及类似printf的函数等:
IfxStdIf_DPipe_onTransmit(&g_ascStandardInterface);
IfxStdIf_DPipe_onReceive(&g_ascStandardInterface);
boolean Ifx_Console_print(pchar format, ...);
同功能1,就比功能1 多了初始化标准接口;
如下方法1,2 需配置标准接口,使用不会出问题,方法三不必需要配置,使用Ifx_Console_print()函数,必须配置,否则程序崩溃。
//方法1--简单好似阻塞读写 --需要配置标准接口(如果不配置,多次后会程序崩溃)
count = (Ifx_SizeT)IfxAsclin_Asc_getReadCount(&g_ascHandle);
IfxAsclin_Asc_read(&g_ascHandle, data, &count, TIME_INFINITE);
IfxAsclin_Asc_write(&g_ascHandle,data, &count, TIME_INFINITE);
//方法2 强制等待根据fifo状态进行阻塞读写(也需要标准接口配置如果不配置,多次后会程序崩溃)
/*
count = (Ifx_SizeT)IfxAsclin_Asc_getReadCount(&g_ascHandle);
while (IfxAsclin_Asc_read(&g_ascHandle, &data, &count, TIME_INFINITE) != TRUE);
while(IfxAsclin_getRxFifoFillLevel(g_ascHandle.asclin) != 0); //双重确认读完成
IfxAsclin_Asc_write(&g_ascHandle,data, &count, TIME_INFINITE);
while(IfxAsclin_getTxFifoFillLevel(g_ascHandle.asclin) != 0);
*/
//方法3 读一个写一个 -- 不需要初始化标准接口
/*
while(count != 0 ){
rx_data= IfxAsclin_Asc_blockingRead(&g_ascHandle);
IfxAsclin_Asc_blockingWrite(&g_ascHandle, rx_data);
}
*/
#ifndef ASCLIN_UART_H_
#define ASCLIN_UART_H_
/*********************************************************************************************************************/
/*------------------------------------------------Function Prototypes------------------------------------------------*/
/*********************************************************************************************************************/
void init_ASCLIN_UART(void); /* Initialization function */
void send_receive_ASCLIN_UART_message(void); /* Send and receive function */
void read2send(void);
#endif /* ASCLIN_UART_H_ */
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "Blinky_LED.h"
#include "interrupt.h"
#include "UART_ASC.h"
#include "Ifx_Console.h"
IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;
void core0_main(void)
{
IfxCpu_enableInterrupts();
/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
* Enable the watchdogs and service them periodically if it is required
*/
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
/* Wait for CPU sync event */
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
IfxCpu_enableInterrupts();
initLED();
initGtmTom();
init_ASCLIN_UART();
Ifx_Console_print("Hello world new\n");
//send_receive_ASCLIN_UART_message();
while(1)
{
//send_receive_ASCLIN_UART_message();
read2send();
}
}
Hello world new是用标准输出接口打印的,这里小口是串口调试助手问题,不必理会。
以上全部方法在TC334芯片上实测有效。。
一定一定要改iLLD库,里面IfxAsclin_Asc_initModuleConfig() 里面的过采样因子和采样位置。
一定一定要改iLLD库,里面IfxAsclin_Asc_initModuleConfig() 里面的过采样因子和采样位置。
一定一定要改iLLD库,里面IfxAsclin_Asc_initModuleConfig() 里面的过采样因子和采样位置。