第三周铁人战队学习总结
ADC環(huán)境例程與庫函數(shù)學(xué)習(xí)
ADC模塊
ADC模塊:即模數(shù)轉(zhuǎn)換模塊/AD轉(zhuǎn)換模塊,功能是將電壓信號(hào)轉(zhuǎn)換為相應(yīng)的數(shù)字信號(hào)。實(shí)際應(yīng)用中,這個(gè)電壓信號(hào)可能由溫度、濕度、壓力等實(shí)際物理量經(jīng)過傳感器和相應(yīng)的變換電路轉(zhuǎn)化而來。經(jīng)過AD轉(zhuǎn)換,MCU(微處理器;單片機(jī))就可以處理這些物理量。
//以下是兩句常用語 #include "headfile.h" #pragma section all "cpu0_dsram"//這兩句為常用 uint16 adc_result;uint16來源
/* 16bit unsigned: 0..65535 [0x0000..0xFFFF]*/ /* [cover parentID={66E964CA-35D5-4013-BB61-1E824636D713}] uint16 [/cover] */ typedef unsigned short uint16;主函數(shù)
int core0_main(void) {disableInterrupts();//禁用中斷get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等adc_init(ADC_0, ADC0_CH0_A0);//初始化ADC0 通道0 使用A0引腳enableInterrupts();//啟動(dòng)中斷 while (TRUE){//通過將A0引腳接到GND或者核心板VCC 查看FSS窗口中打印出來的ADC結(jié)果//A0接到GND時(shí) 結(jié)果應(yīng)該在0附近//A0接到VCC時(shí) 結(jié)果應(yīng)該在4095附近//懸空時(shí) 結(jié)果可能是任意數(shù),沒有任何意義,所以大家不要問懸空的時(shí)候?yàn)槭裁唇Y(jié)果是這么多呢?adc_result = adc_mean_filter(ADC_0, ADC0_CH0_A0, ADC_12BIT, 10);//采集10次求平均 分辨率12位//將結(jié)果通過串口打印,可以先學(xué)習(xí)printf例程,了解如何使用printfprintf("adc_result: %d\n", adc_result);systick_delay_ms(STM0, 100);} }//以下又是一波客套話 #pragma section all restoresystick_delay_ms意義
//------------------------------------以下宏定義用于延時(shí)------------------------------------ #define systick_delay_ms(stmn, time) systick_delay(stmn, time*1000000) //設(shè)置延時(shí)時(shí)間 單位msADC均值濾波
//------------------------------------------------------------------------------------------------------------------- // @brief ADC均值濾波 // @param adcn 選擇ADC模塊(ADC_0、ADC_1、ADC_2) // @param ch 選擇ADC通道 // @param count 均值濾波次數(shù) // @return void // Sample usage: adc_mean_filter(ADC_0, ADC0_CH0_A0, ADC_12BIT, 5);//采集5次 然后返回平均值 //------------------------------------------------------------------------------------------------------------------- uint16 adc_mean_filter(VADCN_enum vadc_n, VADC_CHN_enum vadc_chn, VADC_RES_enum vadc_res, uint8 count) {ZF_ASSERT(count);//斷言次數(shù)不能為0sum = 0;for(i=0; i<count; i++){sum += adc_convert(vadc_n, vadc_chn, vadc_res);}sum = sum/count;return (uint16)sum; }ADC轉(zhuǎn)換
//------------------------------------------------------------------------------------------------------------------- // @brief ADC轉(zhuǎn)換一次即獲取一次信息 // @param adcn 選擇ADC模塊(ADC_0、ADC_1、ADC_2) // @param ch 選擇ADC通道 // @return void // Sample usage: adc_convert(ADC_0, ADC0_CH0_A0, ADC_12BIT); //------------------------------------------------------------------------------------------------------------------- uint16 adc_convert(VADCN_enum vadc_n, VADC_CHN_enum vadc_chn, VADC_RES_enum vadc_res) {Ifx_VADC_RES result;uint8 temp;do{result = IfxVadc_getResult(&MODULE_VADC.G[vadc_n], vadc_chn%16);} while (!result.B.VF);temp = 4 - (vadc_res * 2);return((result.U&0x0fff)>>temp); }LED閃爍模塊
//老客套話了 #include "headfile.h" #pragma section all "cpu0_dsram"uint8 gpio_status; //GPIO(General Purpose I/O Ports)意思為通用輸入/輸出端口,通俗地說,就是一些引腳,可以通過它們輸出高低電平或者通過它們讀入引腳的狀態(tài)-是高電平或是低電平。int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等//需要特別注意P20_2是不能用于輸出的,僅僅只有輸入的功能//需要特別注意P20_2是不能用于輸出的,僅僅只有輸入的功能//需要特別注意P20_2是不能用于輸出的,僅僅只有輸入的功能//設(shè)置P20_8為輸出 默認(rèn)輸出低電平 PUSHPULL:推挽輸出gpio_init(P20_8, GPO, 0, PUSHPULL);gpio_init(P20_9, GPO, 0, PUSHPULL);gpio_init(P21_4, GPO, 0, PUSHPULL);gpio_init(P21_5, GPO, 0, PUSHPULL);//設(shè)置P21_2為輸入 PULLUP:上拉輸入gpio_init(P21_2, GPI, 0, PULLUP); enableInterrupts();while (TRUE){//獲取gpio狀態(tài)gpio_status = gpio_get(P21_2);//將gpio狀態(tài)打印到FSS窗口printf("gpio_status: %d\n", gpio_status);gpio_toggle(P20_8);//翻轉(zhuǎn)IOgpio_toggle(P20_9);gpio_toggle(P21_4);gpio_toggle(P21_5);systick_delay_ms(STM0, 100);} }#pragma section all restore枚舉上下拉選項(xiàng)
// 枚舉上下拉選項(xiàng) typedef enum {NO_PULL, //無輸入上下拉PULLUP, //輸入上拉PULLDOWN, //輸入下拉PUSHPULL, //推挽輸出OPENDRAIN, //開漏輸出 }GPIOMODE_enum;GPIO狀態(tài)獲取
//------------------------------------------------------------------------------------------------------------------- // @brief GPIO狀態(tài)獲取 // @param pin 選擇的引腳 (可選擇范圍由 common.h 內(nèi)PIN_enum枚舉值確定) // @return uint8 0:低電平 1:高電平 // Sample usage: uint8 status = gpio_get(P00_0);//獲取P00_0引腳電平 //------------------------------------------------------------------------------------------------------------------- uint8 gpio_get(PIN_enum pin) {return IfxPort_getPinState(get_port(pin), pin&0x1f); }GPIO 翻轉(zhuǎn)
//------------------------------------------------------------------------------------------------------------------- // @brief GPIO 翻轉(zhuǎn) // @param pin 選擇的引腳 (可選擇范圍由 common.h 內(nèi)PIN_enum枚舉值確定) // @return void // Sample usage: gpio_toggle(P00_0);//P00_0引腳電平翻轉(zhuǎn) //------------------------------------------------------------------------------------------------------------------- void gpio_toggle(PIN_enum pin) {IfxPort_togglePin(get_port(pin), pin&0x1f); }周期定時(shí)器中斷
#include "headfile.h" #pragma section all "cpu0_dsram"int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//在此處調(diào)用各種初始化函數(shù)等//使用CCU6_0模塊的通道0 產(chǎn)生一個(gè) 100ms的周期中斷pit_interrupt_ms(CCU6_0, PIT_CH0, 100);//中斷函數(shù)在isr.c中 函數(shù)名稱為cc60_pit_ch0_isr//中斷相關(guān)的配置參數(shù)在isr_config.h內(nèi)//可配置參數(shù)有 CCU6_0_CH0_INT_SERVICE 和 CCU6_0_CH0_ISR_PRIORITY//CCU6_0_CH0_INT_SERVICE 中斷服務(wù)者,表示改中斷由誰處理,0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值//CCU6_0_CH0_ISR_PRIORITY 中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣//需要特備注意的是 不可以有優(yōu)先級(jí)相同的中斷函數(shù) 每個(gè)中斷的優(yōu)先級(jí)都必須是不一樣的enableInterrupts();while (TRUE){//在isr.c的中斷函數(shù),函數(shù)定義的第二個(gè)參數(shù)固定為0,請(qǐng)不要更改,即使你用CPU1處理中斷也不要更改,需要CPU1處理中斷只需要在isr_config.h內(nèi)修改對(duì)應(yīng)的宏定義即可//程序運(yùn)行之后 PIT中斷每執(zhí)行一次就會(huì)打印一次//將結(jié)果通過串口打印,可以先學(xué)習(xí)printf例程,了解如何使用printf} }#pragma section all restore捕獲/比較單元6(CCU6模塊)
CCU是一個(gè)具有特定應(yīng)用模式的16位高分辨率捕獲和比較單元,主要用于AC驅(qū)動(dòng)控制。特殊操作模式支持使用霍爾傳感器或反電動(dòng)勢(shì)檢測(cè)的無刷DC電機(jī)。
CCU6單元由一個(gè)有三個(gè)捕獲/比較通道的定時(shí)器T12塊和一個(gè)有一個(gè)捕獲比較通道的定時(shí)器T13定時(shí)器塊組成。T12通道可以獨(dú)立產(chǎn)生PWM信號(hào)、接受捕獲的觸發(fā)信號(hào)或他們聯(lián)合產(chǎn)生控制信號(hào)模式來驅(qū)動(dòng)AC電機(jī)或變頻器。
注:捕獲/比較模塊被命名CCU6(捕獲/比較單元6)。該模塊內(nèi)部的捕獲/比較通道被命名為CC6x。
PIT中斷
//------------------------------------以下代碼用于PIT中斷------------------------------------ #define pit_interrupt_ms(ccu6n, pit_ch, time) pit_init(ccu6n, pit_ch, time*1000) //(單位為 毫秒) #define pit_interrupt_us(ccu6n, pit_ch, time) pit_init(ccu6n, pit_ch, time) //(單位為 微秒)PIT中斷參數(shù)相關(guān)定義
//------------PIT中斷參數(shù)相關(guān)定義------------ #define CCU6_0_CH0_INT_SERVICE 0 //定義CCU6_0 PIT通道0中斷服務(wù)類型,即中斷是由誰響應(yīng)處理 0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值 #define CCU6_0_CH0_ISR_PRIORITY 30 //定義CCU6_0 PIT通道0中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣#define CCU6_0_CH1_INT_SERVICE 0 #define CCU6_0_CH1_ISR_PRIORITY 31#define CCU6_1_CH0_INT_SERVICE 0 #define CCU6_1_CH0_ISR_PRIORITY 32#define CCU6_1_CH1_INT_SERVICE 0 #define CCU6_1_CH1_ISR_PRIORITY 33編碼器
#include "headfile.h" #pragma section all "cpu0_dsram"int16 speed;int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等//第一個(gè)參數(shù) 表示選擇使用的定時(shí)器//第二個(gè)參數(shù) 表示選擇的計(jì)數(shù)引腳 計(jì)數(shù)引腳與方向引腳不可交換//第三個(gè)參數(shù) 表示選擇的方向引腳gpt12_init(GPT12_T2, GPT12_T2INB_P33_7, GPT12_T2EUDB_P33_6);enableInterrupts();while (TRUE){speed = gpt12_get(GPT12_T2);gpt12_clear(GPT12_T2);//打印采集到的編碼器數(shù)據(jù),可以先學(xué)習(xí)printf例程,了解如何使用printfprintf("speed: %d\n", speed);systick_delay_ms(STM0, 100);//旋轉(zhuǎn)編碼器越快顯示的數(shù)據(jù)越大,正轉(zhuǎn)數(shù)值為正,反正數(shù)值為負(fù)} }#pragma section all restoreGPT12初始化(編碼器采集)
//------------------------------------------------------------------------------------------------------------------- // @brief GPT12初始化(編碼器采集) // @param gptn 選擇所使用的GPT12定時(shí)器 // @param count_pin 設(shè)置計(jì)數(shù)引腳 // @param dir_pin 設(shè)置計(jì)數(shù)方向引腳 // @return void // Sample usage: gpt12_init(GPT12_T2, GPT12_T2INA_P00_7, GPT12_T2EUDA_P00_8);//使用T2定時(shí)器 P00_7引腳進(jìn)行計(jì)數(shù) 計(jì)數(shù)方向使用P00_8引腳 //------------------------------------------------------------------------------------------------------------------- void gpt12_init(GPTN_enum gptn, GPT_PIN_enum count_pin, GPT_PIN_enum dir_pin) {IfxGpt12_enableModule(&MODULE_GPT120);IfxGpt12_setGpt1BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt1BlockPrescaler_4);IfxGpt12_setGpt2BlockPrescaler(&MODULE_GPT120, IfxGpt12_Gpt2BlockPrescaler_4);gpt12_mux(gptn, count_pin, dir_pin);switch(gptn){case GPT12_T2:{IfxGpt12_T2_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);IfxGpt12_T2_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);IfxGpt12_T2_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);IfxGpt12_T2_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);}break;case GPT12_T3:{IfxGpt12_T3_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);IfxGpt12_T3_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);IfxGpt12_T3_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);IfxGpt12_T3_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);}break;case GPT12_T4:{IfxGpt12_T4_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);IfxGpt12_T4_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);IfxGpt12_T4_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);IfxGpt12_T4_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);}break;case GPT12_T5:{IfxGpt12_T5_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);IfxGpt12_T5_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);IfxGpt12_T5_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);IfxGpt12_T5_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);}break;case GPT12_T6:{IfxGpt12_T6_setCounterInputMode(&MODULE_GPT120, IfxGpt12_CounterInputMode_risingEdgeTxIN);IfxGpt12_T6_setDirectionSource(&MODULE_GPT120, IfxGpt12_TimerDirectionSource_external);IfxGpt12_T6_setMode(&MODULE_GPT120, IfxGpt12_Mode_counter);IfxGpt12_T6_run(&MODULE_GPT120, IfxGpt12_TimerRun_start);}break;} }GPT12定時(shí)器編號(hào)
typedef enum // 枚舉GPT12 定時(shí)器編號(hào) {GPT12_T2,GPT12_T3,GPT12_T4,GPT12_T5,GPT12_T6, }GPTN_enum;枚舉GPT12引腳
//此枚舉定義不允許用戶修改 typedef enum //枚舉GPT12引腳 {GPT12_T2INA_P00_7, GPT12_T2INB_P33_7, //T2定時(shí)器 計(jì)數(shù)引腳可選范圍GPT12_T2EUDA_P00_8, GPT12_T2EUDB_P33_6, //T2定時(shí)器 計(jì)數(shù)方向引腳可選范圍//在LQFP144封裝中沒有P10_4 、P10_7GPT12_T3INA_P02_6, GPT12_T3INB_P10_4, //T3定時(shí)器 計(jì)數(shù)引腳可選范圍GPT12_T3EUDA_P02_7, GPT12_T3EUDB_P10_7, //T3定時(shí)器 計(jì)數(shù)方向引腳可選范圍//在LQFP144封裝中沒有P10_8GPT12_T4INA_P02_8, GPT12_T4INB_P10_8, //T4定時(shí)器 計(jì)數(shù)引腳可選范圍GPT12_T4EUDA_P00_9, GPT12_T4EUDB_P33_5, //T4定時(shí)器 計(jì)數(shù)方向引腳可選范圍GPT12_T5INB_P10_3, GPT12_T5INA_P21_7, //T5定時(shí)器 計(jì)數(shù)引腳可選范圍GPT12_T5EUDB_P10_1, GPT12_T5EUDA_P21_6, //T5定時(shí)器 計(jì)數(shù)方向引腳可選范圍//在LQFP144封裝中沒有P10_0GPT12_T6INB_P10_2, GPT12_T6INA_P20_3, //T6定時(shí)器 計(jì)數(shù)引腳可選范圍GPT12_T6EUDB_P10_0, GPT12_T6EUDA_P20_0, //T6定時(shí)器 計(jì)數(shù)方向引腳可選范圍 }GPT_PIN_enum;GPT12計(jì)數(shù)讀取(編碼器采集)
//------------------------------------------------------------------------------------------------------------------- // @brief GPT12計(jì)數(shù)讀取(編碼器采集) // @param gptn 選擇所使用的GPT12定時(shí)器 // @return void // Sample usage: speed = gpt12_get(GPT12_T2);//使用T2定時(shí)器 //------------------------------------------------------------------------------------------------------------------- int16 gpt12_get(GPTN_enum gptn) {switch(gptn){case GPT12_T2: return (int16)IfxGpt12_T2_getTimerValue(&MODULE_GPT120);case GPT12_T3: return (int16)IfxGpt12_T3_getTimerValue(&MODULE_GPT120);case GPT12_T4: return (int16)IfxGpt12_T4_getTimerValue(&MODULE_GPT120);case GPT12_T5: return (int16)IfxGpt12_T5_getTimerValue(&MODULE_GPT120);case GPT12_T6: return (int16)IfxGpt12_T6_getTimerValue(&MODULE_GPT120);default: return 0;} }清除GPT12計(jì)數(shù)(編碼器采集)
//------------------------------------------------------------------------------------------------------------------- // @brief 清除GPT12計(jì)數(shù)(編碼器采集) // @param gptn 選擇所使用的GPT12定時(shí)器 // @return void // Sample usage: gpt12_clear(GPT12_T2);//使用T2定時(shí)器 //------------------------------------------------------------------------------------------------------------------- void gpt12_clear(GPTN_enum gptn) {switch(gptn){case GPT12_T2: IfxGpt12_T2_setTimerValue(&MODULE_GPT120, 0); break;case GPT12_T3: IfxGpt12_T3_setTimerValue(&MODULE_GPT120, 0); break;case GPT12_T4: IfxGpt12_T4_setTimerValue(&MODULE_GPT120, 0); break;case GPT12_T5: IfxGpt12_T5_setTimerValue(&MODULE_GPT120, 0); break;case GPT12_T6: IfxGpt12_T6_setTimerValue(&MODULE_GPT120, 0); break;} }串口的發(fā)送與中斷接受
#include "headfile.h" #pragma section all "cpu0_dsram"uint8 uart_buff;int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等uart_init(UART_0, 115200, UART0_TX_P14_0, UART0_RX_P14_1);//在本庫中,對(duì)于串口的接收與發(fā)送都是通過中斷完成的,因此想要正常的使用串口功能務(wù)必保證中斷是開啟的,也就是調(diào)用了enableInterrupts()enableInterrupts();//調(diào)用enableInterrupts函數(shù)之后 才開始發(fā)送或者接收數(shù)據(jù)uart_putstr(UART_0, "\n---uart test---\n");//串口的中斷函數(shù)全部都在isr.c中。//串口中斷相關(guān)的配置參數(shù)都在isr_config.h中//可配置參數(shù)有 ERU_CH0_CH4_INT_SERVICE 和 ERU_CH0_CH4_INT_PRIO//UART0_INT_SERVICE 中斷服務(wù)者,表示改中斷由誰處理,0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值//UART0_TX_INT_PRIO 發(fā)送中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣//UART0_RX_INT_PRIO 接收中斷優(yōu)先級(jí)//UART0_ER_INT_PRIO 錯(cuò)誤中斷優(yōu)先級(jí)//其他串口中斷參數(shù)同理//需要特備注意的是 不可以有優(yōu)先級(jí)相同的中斷函數(shù) 每個(gè)中斷的優(yōu)先級(jí)都必須是不一樣的while (TRUE){//查詢是否有數(shù)據(jù),如果有則接收if(uart_query(UART_0, &uart_buff)){//將收到的數(shù)據(jù),再發(fā)出去uart_putchar(UART_0, uart_buff);}//使用usb轉(zhuǎn)ttl連接單片機(jī)的串口,在電腦上打開串口助手,任意發(fā)送字符,//單片機(jī)收到后會(huì)返回發(fā)送的字符,串口助手就會(huì)顯示剛才發(fā)送的東西} }#pragma section all restore串口初始化
//------------------------------------------------------------------------------------------------------------------- // @brief 串口初始化 // @param uartn 串口模塊號(hào)(UART_0,UART_1,UART_2,UART_3) // @param baud 串口波特率 // @param tx_pin 串口發(fā)送引腳 // @param rx_pin 串口接收引腳 // @return uint32 實(shí)際波特率 // Sample usage: uart_init(UART_0,115200,UART0_TX_P14_0,UART0_RX_P14_1); // 初始化串口0 波特率115200 發(fā)送引腳使用P14_0 接收引腳使用P14_1 //------------------------------------------------------------------------------------------------------------------- void uart_init(UARTN_enum uartn, uint32 baud, UART_PIN_enum tx_pin, UART_PIN_enum rx_pin) {boolean interrupt_state = disableInterrupts();volatile Ifx_ASCLIN *moudle = IfxAsclin_getAddress((IfxAsclin_Index)uartn);IfxAsclin_Asc_initModuleConfig(&uart_config, moudle); //初始化化配置結(jié)構(gòu)體uart_set_buffer(uartn);//設(shè)置緩沖區(qū)uart_set_interrupt_priority(uartn);//設(shè)置中斷優(yōu)先級(jí)uart_config.baudrate.prescaler = 4;uart_config.baudrate.baudrate = (float32)baud;uart_config.baudrate.oversampling = IfxAsclin_OversamplingFactor_8;IfxAsclin_Asc_Pins pins;//設(shè)置引腳pins.cts = NULL;pins.rts = NULL;uart_mux(uartn, tx_pin, rx_pin, (uint32 *)&pins.tx, (uint32 *)&pins.rx);pins.rxMode = IfxPort_InputMode_pullUp;pins.txMode = IfxPort_OutputMode_pushPull;pins.pinDriver = IfxPort_PadDriver_cmosAutomotiveSpeed1;uart_config.pins = &pins;IfxAsclin_Asc_initModule(uart_get_handle(uartn), &uart_config);restoreInterrupts(interrupt_state); }GPIO中斷參數(shù)相關(guān)定義
//------------GPIO中斷參數(shù)相關(guān)定義------------ //通道0與通道4是公用一個(gè)中斷函數(shù) 在中斷內(nèi)部通過標(biāo)志位判斷是誰觸發(fā)的中斷 #define ERU_CH0_CH4_INT_SERVICE 0 //定義ERU通道0和通道4中斷服務(wù)類型,即中斷是由誰響應(yīng)處理 0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值 #define ERU_CH0_CH4_INT_PRIO 40 //定義ERU通道0和通道4中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣//通道1與通道5是公用一個(gè)中斷函數(shù) 在中斷內(nèi)部通過標(biāo)志位判斷是誰觸發(fā)的中斷 #define ERU_CH1_CH5_INT_SERVICE 0 //定義ERU通道1和通道5中斷服務(wù)類型,同上 #define ERU_CH1_CH5_INT_PRIO 41 //定義ERU通道1和通道5中斷優(yōu)先級(jí) 同上//通道2與通道6是公用一個(gè)中斷函數(shù) 在中斷內(nèi)部通過標(biāo)志位判斷是誰觸發(fā)的中斷 #define ERU_CH2_CH6_INT_SERVICE 3 //定義ERU通道2和通道6中斷服務(wù)類型,同上 #define ERU_CH2_CH6_INT_PRIO 5 //定義ERU通道2和通道6中斷優(yōu)先級(jí) 同上//通道3與通道7是公用一個(gè)中斷函數(shù) 在中斷內(nèi)部通過標(biāo)志位判斷是誰觸發(fā)的中斷 #define ERU_CH3_CH7_INT_SERVICE 0 //定義ERU通道3和通道7中斷服務(wù)類型,同上 #define ERU_CH3_CH7_INT_PRIO 43 //定義ERU通道3和通道7中斷優(yōu)先級(jí) 同上讀取串口接收的數(shù)據(jù)(查詢接收)
//------------------------------------------------------------------------------------------------------------------- // @brief 讀取串口接收的數(shù)據(jù)(查詢接收) // @param uartn 串口模塊號(hào)(UART_0,UART_1,UART_2,UART_3) // @param *dat 接收數(shù)據(jù)的地址 // @return uint8 1:接收成功 0:未接收到數(shù)據(jù) // Sample usage: uint8 dat; uart_query(UART_0,&dat); // 接收串口0數(shù)據(jù) 存在在dat變量里 //------------------------------------------------------------------------------------------------------------------- uint8 uart_query(UARTN_enum uartn, uint8 *dat) {if(IfxAsclin_Asc_getReadCount(uart_get_handle(uartn)) >0){*dat = IfxAsclin_Asc_blockingRead(uart_get_handle(uartn));return 1;}return 0; }串口字節(jié)輸出
//------------------------------------------------------------------------------------------------------------------- // @brief 串口字節(jié)輸出 // @param uartn 串口模塊號(hào)(UART_0,UART_1,UART_2,UART_3) // @param dat 需要發(fā)送的字節(jié) // @return void // Sample usage: uart_putchar(UART_0, 0xA5); // 串口0發(fā)送0xA5 //------------------------------------------------------------------------------------------------------------------- void uart_putchar(UARTN_enum uartn, uint8 dat) { // IfxAsclin_Asc_blockingWrite(uart_get_handle(uartn),dat);Ifx_SizeT count = 1;(void)IfxAsclin_Asc_write(uart_get_handle(uartn), &dat, &count, TIME_INFINITE); }串口發(fā)送數(shù)組
//------------------------------------------------------------------------------------------------------------------- // @brief 串口發(fā)送數(shù)組 // @param uartn 串口模塊號(hào)(UART_0,UART_1,UART_2,UART_3) // @param *buff 要發(fā)送的數(shù)組地址 // @param len 發(fā)送長(zhǎng)度 // @return void // Sample usage: uart_putbuff(UART_0,&a[0],5); //------------------------------------------------------------------------------------------------------------------- void uart_putbuff(UARTN_enum uartn, uint8 *buff, uint32 len) {while(len){uart_putchar(uartn, *buff);len--;buff++;} }串口發(fā)送字符串
//------------------------------------------------------------------------------------------------------------------- // @brief 串口發(fā)送字符串 // @param uartn 串口模塊號(hào)(UART_0,UART_1,UART_2,UART_3) // @param *str 要發(fā)送的字符串地址 // @return void // Sample usage: uart_putstr(UART_0,"i lvoe you"); //------------------------------------------------------------------------------------------------------------------- void uart_putstr(UARTN_enum uartn, const int8 *str) {while(*str){uart_putchar(uartn, *str++);} }Printf函數(shù)打印
#include "headfile.h" #pragma section all "cpu0_dsram"uint16 num;int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等printf("printf demo\n");enableInterrupts();while (TRUE){num++;printf("printf num :%d\n", num);systick_delay_ms(STM0, 100);//注意事項(xiàng)1 printf打印的數(shù)據(jù)會(huì)通過串口發(fā)送出去//注意事項(xiàng)2 printf所使用的串口和波特率可以在TC264_config.h文件中修改//注意事項(xiàng)3 printf所使用的串口默認(rèn)在get_clk函數(shù)中進(jìn)行了初始化,如果不想使用printf則可以在TC264_config.h文件中將PRINTF_ENABLE宏定義設(shè)置為0即可} }#pragma section all restoreGPIO觸發(fā)中斷
#include "headfile.h" #pragma section all "cpu0_dsram"int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等//特別注意通道2 與 通道3都被攝像頭占用,由于中斷共用的關(guān)系,因此通道6 與 通道7也不能使用//TC264的外部中斷不像K60單片機(jī)那樣所有IO都支持,TC264只有部分支持具體可以查看zf_eru.h中ERU_PIN_enum枚舉定義eru_init(ERU_CH0_REQ0_P15_4, RISING); //ERU通道0 使用P15_4引腳 上升沿中斷eru_init(ERU_CH4_REQ13_P15_5, RISING); //ERU通道4 使用P15_5引腳 上升沿中斷//通道0與4共用中斷,中斷內(nèi)通過標(biāo)志位判斷eru_init(ERU_CH1_REQ10_P14_3, RISING); //ERU通道1 使用P14_3引腳 上升沿中斷eru_init(ERU_CH5_REQ1_P15_8, RISING); //ERU通道5 使用P15_8引腳 上升沿中斷//通道1與5共用中斷,中斷內(nèi)通過標(biāo)志位判斷//中斷函數(shù)在isr.c中//函數(shù)名稱分別為eru_ch0_ch4_isr 與 eru_ch1_ch5_isr//中斷相關(guān)的配置參數(shù)在isr_config.h內(nèi)//可配置參數(shù)有 ERU_CH0_CH4_INT_SERVICE 和 ERU_CH0_CH4_INT_PRIO//ERU_CH0_CH4_INT_SERVICE 中斷服務(wù)者,表示改中斷由誰處理,0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值//ERU_CH0_CH4_INT_PRIO 中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣//ERU其他中斷也是同理//需要特備注意的是 不可以有優(yōu)先級(jí)相同的中斷函數(shù) 每個(gè)中斷的優(yōu)先級(jí)都必須是不一樣的enableInterrupts();while (TRUE){//在isr.c的中斷函數(shù),函數(shù)定義的第二個(gè)參數(shù)固定為0,請(qǐng)不要更改,即使你用CPU1處理中斷也不要更改,需要CPU1處理中斷只需要在isr_config.h內(nèi)修改對(duì)應(yīng)的宏定義即可//程序運(yùn)行之后,使用杜邦線將P15_4、P15_5、P14_3、P15_8連接到GND,然后在斷開,在連接如此往復(fù)//將提示信息通過串口打印,可以先學(xué)習(xí)printf例程,了解如何使用printf} }#pragma section all restoreeru初始化(gpio中斷)
//------------------------------------------------------------------------------------------------------------------- // @brief eru初始化(gpio中斷) // @param eru_pin 設(shè)置eru通道及引腳 // @param trigger 設(shè)置觸發(fā)方式 // @return void // Sample usage: eru_init(ERU_CH0_REQ0_P15_4, RISING);//eru通道0 使用P10_7引腳,上升沿觸發(fā)中斷 //------------------------------------------------------------------------------------------------------------------- void eru_init(ERU_PIN_enum eru_pin, TRIGGER_enum trigger) {boolean interrupt_state = disableInterrupts();IfxScu_Req_In *reqPin;reqPin = eru_mux(eru_pin);IfxScuEru_initReqPin(reqPin, IfxPort_InputMode_pullUp);IfxScuEru_InputChannel inputChannel = (IfxScuEru_InputChannel)reqPin->channelId;IfxScuEru_InputNodePointer triggerSelect = (IfxScuEru_InputNodePointer)(eru_pin/3);IfxScuEru_OutputChannel outputChannel = (IfxScuEru_OutputChannel)(eru_pin/3);switch(trigger){case RISING:{IfxScuEru_disableFallingEdgeDetection(inputChannel);IfxScuEru_enableRisingEdgeDetection(inputChannel);}break;case FALLING:{IfxScuEru_enableFallingEdgeDetection(inputChannel);IfxScuEru_disableRisingEdgeDetection(inputChannel);}break;case BOTH:{IfxScuEru_enableFallingEdgeDetection(inputChannel);IfxScuEru_enableRisingEdgeDetection(inputChannel);}break;default: ZF_ASSERT(FALSE);}IfxScuEru_enableTriggerPulse(inputChannel);IfxScuEru_connectTrigger(inputChannel, triggerSelect);IfxScuEru_setFlagPatternDetection(outputChannel, inputChannel, TRUE);IfxScuEru_enablePatternDetectionTrigger(outputChannel);IfxScuEru_setInterruptGatingPattern(outputChannel, IfxScuEru_InterruptGatingPattern_alwaysActive);volatile Ifx_SRC_SRCR *src = &MODULE_SRC.SCU.SCU.ERU[(int)outputChannel % 4];IfxSrc_Tos eru_service;uint8 eru_priority;switch((eru_pin/3)%4){case 0:{eru_service = (IfxSrc_Tos)ERU_CH0_CH4_INT_SERVICE;eru_priority = ERU_CH0_CH4_INT_PRIO;}break;case 1:{eru_service = (IfxSrc_Tos)ERU_CH1_CH5_INT_SERVICE;eru_priority = ERU_CH1_CH5_INT_PRIO;}break;case 2:{eru_service = (IfxSrc_Tos)ERU_CH2_CH6_INT_SERVICE;eru_priority = ERU_CH2_CH6_INT_PRIO;}break;case 3:{eru_service = (IfxSrc_Tos)ERU_CH3_CH7_INT_SERVICE;eru_priority = ERU_CH3_CH7_INT_PRIO;}break;} #pragma warning 507IfxSrc_init(src, eru_service, eru_priority); #pragma warning defaultIfxSrc_enable(src);restoreInterrupts(interrupt_state); }枚舉ERU通道
typedef enum // 枚舉ERU通道 {//一個(gè)通道只能選擇其中一個(gè)引腳作為 外部中斷的輸入//例如通道0 可選引腳為P10_7 和 P15_4,//在LQFP144封裝中沒有P10_7ERU_CH0_REQ4_P10_7 = 0*3, ERU_CH0_REQ0_P15_4, //通道0可選引腳 LQFP沒有P10_7引腳//在LQFP144封裝中沒有P10_8ERU_CH1_REQ5_P10_8 = 1*3, ERU_CH1_REQ10_P14_3, //通道1可選引腳 LQFP沒有P10_8引腳ERU_CH2_REQ7_P00_4 = 2*3, ERU_CH2_REQ14_P02_1, ERU_CH2_REQ2_P10_2, //通道2可選引腳ERU_CH3_REQ6_P02_0 = 3*3, ERU_CH3_REQ3_P10_3, ERU_CH3_REQ15_P14_1, //通道3可選引腳//通道4與通道0 共用中斷函數(shù) 在中斷內(nèi)通過判斷標(biāo)志位來識(shí)別是哪個(gè)通道觸發(fā)的中斷ERU_CH4_REQ13_P15_5 = 4*3, ERU_CH4_REQ8_P33_7, //通道4可選引腳//通道5與通道1 共用中斷函數(shù)ERU_CH5_REQ1_P15_8 = 5*3, //通道5可選引腳//通道6與通道2 共用中斷函數(shù)ERU_CH6_REQ12_P11_10 = 6*3, ERU_CH6_REQ9_P20_0, //通道6可選引腳//通道7與通道3 共用中斷函數(shù)ERU_CH7_REQ16_P15_1 = 7*3, ERU_CH7_REQ11_P20_9, //通道7可選引腳 }ERU_PIN_enum;//特別注意通道2 與 通道3都被攝像頭占用,意味著只有兩個(gè)外部中斷可供用戶使用EEPROM(Dflash)保存參數(shù)
概述
在實(shí)際的應(yīng)用中,保存在單片機(jī)RAM中的數(shù)據(jù),掉電后就丟失了,保存在單片機(jī)的FLASH中的數(shù)據(jù),又不能隨意改變,也就是不能用它來記錄變化的數(shù)值。但是在某些場(chǎng)合,我們又確實(shí)**需要記錄下某些數(shù)據(jù),而它們還時(shí)常需要改變或更新,掉電之后數(shù)據(jù)還不能丟失。**比如,我們的家用電表度數(shù),電視機(jī)里邊的頻道記憶,一般都是使用EEPROM來保存數(shù)據(jù),特點(diǎn)就是掉電后存儲(chǔ)的數(shù)據(jù)不丟失。
一般情況下,EEPROM擁有30萬到100萬次的壽命,也就是它可以反復(fù)寫入30-100萬次,而讀取次數(shù)是無限的。
24C02是一個(gè)常用的基于IIC通信協(xié)議的EEPROM元件,例如ATMEL公司的AT24C02、CATALYST公司的CAT24C02和ST公司的ST24C02等芯片。
IIC是一個(gè)通信協(xié)議,它擁有嚴(yán)密的通信時(shí)序邏輯要求,而EEPROM是一個(gè)元件,只是這個(gè)元件采樣了IIC協(xié)議的接口與單片機(jī)相連而已,二者并沒有必然的聯(lián)系,EEPROM可以用其它接口,I2C也可以用在其它很多器件上。
#include "headfile.h" #pragma section all "cpu0_dsram"#define EXAMPLE_EEPROM_SECTOR (0)uint8 write_data1; uint16 write_data2; uint32 write_data3; float write_data4;uint8 read_data1; uint16 read_data2; uint32 read_data3; float read_data4;uint32 write_buf;int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等write_data1 = 66;write_data2 = 6666;write_data3 = 666666;write_data4 = 6666.66;//檢查當(dāng)前頁是否有數(shù)據(jù),如果有數(shù)據(jù)則需要擦除整個(gè)扇區(qū),if(flash_check(EXAMPLE_EEPROM_SECTOR, 0) || flash_check(EXAMPLE_EEPROM_SECTOR, 1) || flash_check(EXAMPLE_EEPROM_SECTOR, 2) || flash_check(EXAMPLE_EEPROM_SECTOR, 3)){eeprom_erase_sector(EXAMPLE_EEPROM_SECTOR);}//當(dāng)寫入的數(shù)據(jù)不是32位時(shí),建議將數(shù)據(jù)放入uint32 類型的變量中,在將該變量作為參數(shù)傳入到eeprom_page_program函數(shù)write_buf = write_data1;//將數(shù)據(jù)寫入EXAMPLE_EEPROM_SECTOR扇區(qū)的第0頁eeprom_page_program(EXAMPLE_EEPROM_SECTOR, 0, &write_buf);write_buf = write_data2;eeprom_page_program(EXAMPLE_EEPROM_SECTOR, 1, &write_buf);write_buf = write_data3;eeprom_page_program(EXAMPLE_EEPROM_SECTOR, 2, &write_buf);//保存浮點(diǎn)數(shù)的時(shí)候,使用float_conversion_uint32宏定義進(jìn)行轉(zhuǎn)換后在保存write_buf = float_conversion_uint32(write_data4);eeprom_page_program(EXAMPLE_EEPROM_SECTOR, 3, &write_buf);//讀取eeprom中的數(shù)據(jù)read_data1 = flash_read(EXAMPLE_EEPROM_SECTOR, 0, uint8);read_data2 = flash_read(EXAMPLE_EEPROM_SECTOR, 1, uint16);read_data3 = flash_read(EXAMPLE_EEPROM_SECTOR, 2, uint32);read_data4 = flash_read(EXAMPLE_EEPROM_SECTOR, 3, float);printf("read_data1: %d\n", read_data1);printf("read_data2: %d\n", read_data2);printf("read_data3: %ld\n", read_data3);printf("read_data4: %f\n", read_data4);enableInterrupts();while (TRUE){} }#pragma section all restore校驗(yàn)FLASH是否有數(shù)據(jù)
//------------------------------------------------------------------------------------------------------------------- // @brief 校驗(yàn)FLASH是否有數(shù)據(jù) // @param sector_num 需要寫入的扇區(qū)編號(hào) 參數(shù)范圍0-11 // @param page_num 當(dāng)前扇區(qū)頁的編號(hào) 參數(shù)范圍0-1023 // @return 返回1有數(shù)據(jù),返回0沒有數(shù)據(jù),如果需要對(duì)有數(shù)據(jù)的區(qū)域?qū)懭胄碌臄?shù)據(jù)則應(yīng)該對(duì)所在扇區(qū)進(jìn)行擦除操作 // @since v1.0 // Sample usage: flash_check(0,0);//校驗(yàn)0號(hào)扇區(qū),第0頁是否有數(shù)據(jù) //------------------------------------------------------------------------------------------------------------------- uint8 flash_check(uint32 sector_num, uint32 page_num) {ZF_ASSERT(EEPROM_SECTOR_NUM>sector_num);ZF_ASSERT(EEPROM_SECTOR_PAGE_NUM>page_num);uint32 sector_addr = IfxFlash_dFlashTableEepLog[sector_num].start;uint32 page_addr = sector_addr + page_num * IFXFLASH_DFLASH_PAGE_LENGTH;uint32 temp = *(uint32 *)page_addr;if(0 != temp) return 1;return 0; }擦除扇區(qū)
//------------------------------------------------------------------------------------------------------------------- // @brief 擦除扇區(qū) // @param sector_num 需要寫入的扇區(qū)編號(hào) 參數(shù)范圍0-11 // @return void // @since v1.0 // Sample usage: eeprom_erase_sector(0); //------------------------------------------------------------------------------------------------------------------- void eeprom_erase_sector(uint32 sector_num) {ZF_ASSERT(EEPROM_SECTOR_NUM>sector_num);uint32 flash = 0;uint16 end_init_sfty_pw;uint32 sector_addr = IfxFlash_dFlashTableEepLog[sector_num].start;end_init_sfty_pw = IfxScuWdt_getSafetyWatchdogPassword();IfxScuWdt_clearSafetyEndinit(end_init_sfty_pw);IfxFlash_eraseSector(sector_addr);IfxScuWdt_setSafetyEndinit(end_init_sfty_pw);IfxFlash_waitUnbusy(flash, IfxFlash_FlashType_D0); }編程一頁
//------------------------------------------------------------------------------------------------------------------- // @brief 編程一頁 // @param sector_num 需要寫入的扇區(qū)編號(hào) 參數(shù)范圍0-11 // @param page_num 需要寫入的頁編號(hào) 參數(shù)范圍0-1023 // @param buf 需要寫入的數(shù)據(jù)地址 傳入的數(shù)組類型必須為uint32 // @return void // @since v1.0 // Sample usage: eeprom_page_program(0,0, &buf); //------------------------------------------------------------------------------------------------------------------- void eeprom_page_program(uint32 sector_num, uint32 page_num, uint32 *buf) {ZF_ASSERT(EEPROM_SECTOR_NUM>sector_num);ZF_ASSERT(EEPROM_SECTOR_PAGE_NUM>page_num);uint32 errors = 0;uint32 flash = 0;uint16 end_init_sfty_pw;uint32 sector_addr = IfxFlash_dFlashTableEepLog[sector_num].start;end_init_sfty_pw = IfxScuWdt_getSafetyWatchdogPassword();uint32 page_addr = sector_addr + page_num * IFXFLASH_DFLASH_PAGE_LENGTH;errors = IfxFlash_enterPageMode(page_addr);ZF_ASSERT(0 == errors);IfxFlash_waitUnbusy(flash, IfxFlash_FlashType_D0);IfxFlash_loadPage(page_addr, buf[0], 0);IfxScuWdt_clearSafetyEndinit(end_init_sfty_pw);IfxFlash_writePage(page_addr);IfxScuWdt_setSafetyEndinit(end_init_sfty_pw);IfxFlash_waitUnbusy(flash, IfxFlash_FlashType_D0); }將浮點(diǎn)數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)據(jù)
//------------------------------------------------------------------------------------------------------------------- // @brief 將浮點(diǎn)數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)據(jù) // @param float_data 需要轉(zhuǎn)換的浮點(diǎn)數(shù) // @return 返回整型數(shù)據(jù) // @since v1.0 // Sample usage: float_conversion_uint32(write_data4); //------------------------------------------------------------------------------------------------------------------- #define float_conversion_uint32(float_data) (*(uint32 *)&float_data)uint8 flash_check(uint32 sector_num, uint32 page_num); void eeprom_erase_sector(uint32 sector_num); void eeprom_page_program(uint32 sector_num, uint32 page_num, uint32 *buf);#endif使用宏定義對(duì)flash進(jìn)行數(shù)據(jù)讀取
//------------------------------------------------------------------------------------------------------------------- // @brief 使用宏定義對(duì)flash進(jìn)行數(shù)據(jù)讀取 // @param sector_num 需要寫入的扇區(qū)編號(hào) // @param page_num 需要讀取的頁 // @param type 讀取的數(shù)據(jù)類型 // @return 返回給定地址的數(shù)據(jù) // @since v1.0 // Sample usage: flash_read(0,0,uint32);//讀取0號(hào)扇區(qū) 第0也數(shù)據(jù) 類型為uint32 //------------------------------------------------------------------------------------------------------------------- #define flash_read(sector_num,page_num,type) (*(type *)((uint32)((EEPROM_BASE_ADDR + (sector_num)*EEPROM_SECTOR_SIZE) + (page_num*8))))GTM模塊輸出PWM以及設(shè)定占空比
#include "headfile.h" #pragma section all "cpu0_dsram"int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等gtm_pwm_init(ATOM0_CH4_P02_4, 50, 0);//ATOM 0模塊的通道4 使用P02_4引腳輸出PWM PWM頻率50HZ 占空比百分之0/GTM_ATOM0_PWM_DUTY_MAX*100 GTM_ATOM0_PWM_DUTY_MAX宏定義在zf_gtm_pwm.hgtm_pwm_init(ATOM0_CH5_P02_5, 1000, 0);gtm_pwm_init(ATOM0_CH6_P02_6, 10000, 0);gtm_pwm_init(ATOM0_CH7_P02_7, 30000, 0);gtm_pwm_init(ATOM1_CH7_P00_8, 30000, 5000);//每個(gè)通道都可以輸出不同頻率的PWMpwm_duty(ATOM0_CH4_P02_4, 5000);//設(shè)置占空比為百分之5000/GTM_ATOM0_PWM_DUTY_MAX*100pwm_duty(ATOM0_CH5_P02_5, 5000);pwm_duty(ATOM0_CH6_P02_6, 5000);pwm_duty(ATOM0_CH7_P02_7, 5000);enableInterrupts();while (TRUE){} }#pragma section all restorePWM初始化
//------------------------------------------------------------------------------------------------------------------- // @brief PWM初始化 // @param pwmch PWM通道號(hào)及引腳 // @param freq PWM頻率 // @param duty PWM占空比 // @return void // Sample usage: gtm_pwm_init(ATOM0_CH7_P02_7, 50, 1000); //ATOM 0模塊的通道7 使用P02_7引腳輸出PWM PWM頻率50HZ 占空比百分之1000/GTM_ATOM0_PWM_DUTY_MAX*100 // GTM_ATOM0_PWM_DUTY_MAX宏定義在zf_gtm_pwm.h 默認(rèn)為10000 //------------------------------------------------------------------------------------------------------------------- void gtm_pwm_init(ATOM_PIN_enum pwmch, uint32 freq, uint32 duty) {IfxGtm_Atom_Pwm_Config g_atomConfig;IfxGtm_Atom_Pwm_Driver g_atomDriver;IfxGtm_Atom_ToutMap *atom_channel;atom_channel = gtm_atom_mux(pwmch);switch(atom_channel->atom){case 0: IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, duty <= GTM_ATOM0_PWM_DUTY_MAX); break;case 1: IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, duty <= GTM_ATOM1_PWM_DUTY_MAX); break;case 2: IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, duty <= GTM_ATOM2_PWM_DUTY_MAX); break;case 3: IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, duty <= GTM_ATOM3_PWM_DUTY_MAX); break;}IfxGtm_enable(&MODULE_GTM);if(!(MODULE_GTM.CMU.CLK_EN.U & 0x2)){IfxGtm_Cmu_setClkFrequency(&MODULE_GTM, IfxGtm_Cmu_Clk_0, CLK_FREQ);IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_CLK0);}IfxGtm_Atom_Pwm_initConfig(&g_atomConfig, &MODULE_GTM);g_atomConfig.atom = atom_channel->atom;g_atomConfig.atomChannel = atom_channel->channel;g_atomConfig.period = CLK_FREQ/freq;g_atomConfig.pin.outputPin = atom_channel;g_atomConfig.synchronousUpdateEnabled = TRUE;switch(atom_channel->atom){case 0: g_atomConfig.dutyCycle = (uint32)((uint64)duty * g_atomConfig.period / GTM_ATOM0_PWM_DUTY_MAX); break;case 1: g_atomConfig.dutyCycle = (uint32)((uint64)duty * g_atomConfig.period / GTM_ATOM1_PWM_DUTY_MAX); break;case 2: g_atomConfig.dutyCycle = (uint32)((uint64)duty * g_atomConfig.period / GTM_ATOM2_PWM_DUTY_MAX); break;case 3: g_atomConfig.dutyCycle = (uint32)((uint64)duty * g_atomConfig.period / GTM_ATOM3_PWM_DUTY_MAX); break;}IfxGtm_Atom_Pwm_init(&g_atomDriver, &g_atomConfig);IfxGtm_Atom_Pwm_start(&g_atomDriver, TRUE); }PWM占空比設(shè)置
//------------------------------------------------------------------------------------------------------------------- // @brief PWM占空比設(shè)置 // @param pwmch PWM通道號(hào)及引腳 // @param duty PWM占空比 // @return void // Sample usage: pwm_duty(ATOM0_CH7_P02_7, 5000);//設(shè)置占空比為百分之5000/GTM_ATOM0_PWM_DUTY_MAX*100 // GTM_ATOM0_PWM_DUTY_MAX宏定義在zf_gtm_pwm.h 默認(rèn)為10000 //------------------------------------------------------------------------------------------------------------------- void pwm_duty(ATOM_PIN_enum pwmch, uint32 duty) {uint32 period;IfxGtm_Atom_ToutMap *atom_channel;atom_channel = gtm_atom_mux(pwmch);period = IfxGtm_Atom_Ch_getCompareZero(&MODULE_GTM.ATOM[atom_channel->atom], atom_channel->channel);switch(atom_channel->atom){case 0: duty = (uint32)((uint64)duty * period / GTM_ATOM0_PWM_DUTY_MAX); break;case 1: duty = (uint32)((uint64)duty * period / GTM_ATOM1_PWM_DUTY_MAX); break;case 2: duty = (uint32)((uint64)duty * period / GTM_ATOM2_PWM_DUTY_MAX); break;case 3: duty = (uint32)((uint64)duty * period / GTM_ATOM3_PWM_DUTY_MAX); break;}IfxGtm_Atom_Ch_setCompareOneShadow(&MODULE_GTM.ATOM[atom_channel->atom], atom_channel->channel, duty); }GTM_ATOM0_PWM_DUTY_MAX宏定義
#define GTM_ATOM0_PWM_DUTY_MAX 10000 //GTM_ATOM0 PWM最大占空比 最大占空比越大占空比的步進(jìn)值越小 #define GTM_ATOM1_PWM_DUTY_MAX 10000 //GTM_ATOM1 PWM最大占空比 最大占空比越大占空比的步進(jìn)值越小 #define GTM_ATOM2_PWM_DUTY_MAX 10000 //GTM_ATOM2 PWM最大占空比 最大占空比越大占空比的步進(jìn)值越小 #define GTM_ATOM3_PWM_DUTY_MAX 10000 //GTM_ATOM3 PWM最大占空比 最大占空比越大占空比的步進(jìn)值越小中斷優(yōu)先級(jí)設(shè)置
#include "headfile.h" #pragma section all "cpu0_dsram"uint16 adc_result;int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//本例程沒有代碼//中斷優(yōu)先級(jí)都在isr_config.h中 進(jìn)行設(shè)置//以及中斷的服務(wù)者也在isr_config.h中 進(jìn)行設(shè)置//所有的中斷 優(yōu)先級(jí)務(wù)必保證不一樣,不能有重復(fù)的優(yōu)先級(jí)//在uart、pit、GPIO中斷例程中的備注都有提到enableInterrupts();while (TRUE){//在isr.c的中斷函數(shù),函數(shù)定義的第二個(gè)參數(shù)固定為0,請(qǐng)不要更改,即使你用CPU1處理中斷也不要更改,需要CPU1處理中斷只需要在isr_config.h內(nèi)修改對(duì)應(yīng)的宏定義即可} }#pragma section all restore中斷優(yōu)先級(jí)及中斷服務(wù)者
#ifndef _isr_config_h #define _isr_config_h//ISR_PRIORITY: TC264具有255個(gè)中斷優(yōu)先級(jí)可以設(shè)置 1-255,0優(yōu)先級(jí)表示不開啟中斷,255為最高優(yōu)先級(jí) //特別注意 //中斷優(yōu)先級(jí)不能設(shè)置一樣,所有中斷優(yōu)先級(jí)都必須設(shè)置為不一樣的值 //特別注意//INT_SERVICE: 宏定義決定中斷由誰處理,也稱為服務(wù)提供者(在TC264中,中斷被叫做服務(wù)),可設(shè)置范圍0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值//如果INT_SERVICE設(shè)置為3的話,ISR_PRIORITY的可設(shè)置范圍則是0-47。//------------PIT中斷參數(shù)相關(guān)定義------------ #define CCU6_0_CH0_INT_SERVICE 0 //定義CCU6_0 PIT通道0中斷服務(wù)類型,即中斷是由誰響應(yīng)處理 0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值 #define CCU6_0_CH0_ISR_PRIORITY 30 //定義CCU6_0 PIT通道0中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣#define CCU6_0_CH1_INT_SERVICE 0 #define CCU6_0_CH1_ISR_PRIORITY 31#define CCU6_1_CH0_INT_SERVICE 0 #define CCU6_1_CH0_ISR_PRIORITY 32#define CCU6_1_CH1_INT_SERVICE 0 #define CCU6_1_CH1_ISR_PRIORITY 33//------------GPIO中斷參數(shù)相關(guān)定義------------ //通道0與通道4是公用一個(gè)中斷函數(shù) 在中斷內(nèi)部通過標(biāo)志位判斷是誰觸發(fā)的中斷 #define ERU_CH0_CH4_INT_SERVICE 0 //定義ERU通道0和通道4中斷服務(wù)類型,即中斷是由誰響應(yīng)處理 0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值 #define ERU_CH0_CH4_INT_PRIO 40 //定義ERU通道0和通道4中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣//通道1與通道5是公用一個(gè)中斷函數(shù) 在中斷內(nèi)部通過標(biāo)志位判斷是誰觸發(fā)的中斷 #define ERU_CH1_CH5_INT_SERVICE 0 //定義ERU通道1和通道5中斷服務(wù)類型,同上 #define ERU_CH1_CH5_INT_PRIO 41 //定義ERU通道1和通道5中斷優(yōu)先級(jí) 同上//通道2與通道6是公用一個(gè)中斷函數(shù) 在中斷內(nèi)部通過標(biāo)志位判斷是誰觸發(fā)的中斷 #define ERU_CH2_CH6_INT_SERVICE 3 //定義ERU通道2和通道6中斷服務(wù)類型,同上 #define ERU_CH2_CH6_INT_PRIO 5 //定義ERU通道2和通道6中斷優(yōu)先級(jí) 同上//通道3與通道7是公用一個(gè)中斷函數(shù) 在中斷內(nèi)部通過標(biāo)志位判斷是誰觸發(fā)的中斷 #define ERU_CH3_CH7_INT_SERVICE 0 //定義ERU通道3和通道7中斷服務(wù)類型,同上 #define ERU_CH3_CH7_INT_PRIO 43 //定義ERU通道3和通道7中斷優(yōu)先級(jí) 同上//------------DMA中斷參數(shù)相關(guān)定義------------ #define ERU_DMA_INT_SERVICE 0 //ERU觸發(fā)DMA中斷服務(wù)類型,即中斷是由誰響應(yīng)處理 0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值 #define ERU_DMA_INT_PRIO 60 //ERU觸發(fā)DMA中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣//------------串口中斷參數(shù)相關(guān)定義------------ #define UART0_INT_SERVICE 0 //定義串口0中斷服務(wù)類型,即中斷是由誰響應(yīng)處理 0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值 #define UART0_TX_INT_PRIO 10 //定義串口0發(fā)送中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣 #define UART0_RX_INT_PRIO 11 //定義串口0接收中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣 #define UART0_ER_INT_PRIO 12 //定義串口0錯(cuò)誤中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣#define UART1_INT_SERVICE 0 #define UART1_TX_INT_PRIO 13 #define UART1_RX_INT_PRIO 14 #define UART1_ER_INT_PRIO 15#define UART2_INT_SERVICE 0 #define UART2_TX_INT_PRIO 16 #define UART2_RX_INT_PRIO 17 #define UART2_ER_INT_PRIO 18#define UART3_INT_SERVICE 0 #define UART3_TX_INT_PRIO 19 #define UART3_RX_INT_PRIO 20 #define UART3_ER_INT_PRIO 21#endif系統(tǒng)定時(shí)器完成延時(shí)與計(jì)時(shí)功能
#include "headfile.h" #pragma section all "cpu0_dsram"uint16 time;int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等enableInterrupts();while (TRUE){systick_start(STM1); //使用STM1 進(jìn)行計(jì)時(shí)systick_delay_ms(STM0, 100); //延時(shí)100MS 使用STM0定時(shí)器 也可以使用STM1定時(shí)器time = systick_getval_ms(STM1); //讀取STM1計(jì)時(shí)時(shí)間printf("delay time: %dms\n", time);} }#pragma section all restoresystick定時(shí)器啟動(dòng)
//------------------------------------------------------------------------------------------------------------------- // @brief systick定時(shí)器啟動(dòng) // @param stmn 選擇使用的模塊 // @return void // Sample usage: systick_start(STM0);//記錄下當(dāng)前的時(shí)間 //------------------------------------------------------------------------------------------------------------------- void systick_start(STMN_enum stmn) {systick_count[stmn] = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)stmn)); }systick延時(shí)函數(shù)
//------------------------------------------------------------------------------------------------------------------- // @brief systick延時(shí)函數(shù) // @param time 需要延時(shí)的時(shí)間 // @return void // Sample usage: 無需用戶調(diào)用,用戶請(qǐng)使用h文件中的宏定義 //------------------------------------------------------------------------------------------------------------------- void systick_delay(STMN_enum stmn, uint32 time) {uint32 stm_clk;stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)stmn));IfxStm_waitTicks(IfxStm_getAddress((IfxStm_Index)stmn), (uint32)((uint64)stm_clk*time/1000000000)); }獲得當(dāng)前System tick timer的值
//------------------------------------------------------------------------------------------------------------------- // @brief 獲得當(dāng)前System tick timer的值 // @param stmn 選擇使用的模塊 // @return uint32 返回從開始到現(xiàn)在的時(shí)間(單位10ns) // Sample usage: uint32 tim = systick_getval(STM0); //------------------------------------------------------------------------------------------------------------------- uint32 systick_getval(STMN_enum stmn) {uint32 time;uint32 stm_clk;stm_clk = IfxStm_getFrequency(IfxStm_getAddress((IfxStm_Index)stmn));time = IfxStm_getLower(IfxStm_getAddress((IfxStm_Index)stmn)) - systick_count[stmn];time = (uint32)((uint64)time * 100000000 / stm_clk);return time; }單片機(jī)的雙核運(yùn)行
#include "headfile.h" #pragma section all "cpu0_dsram"uint16 adc_result;int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等//雙核的使用其實(shí)很簡(jiǎn)單,就是在兩個(gè)main中編寫不用的程序即可//本例程使用核心0 閃爍P20_8的LED 核心1閃爍P20_9的LEDgpio_init(P20_8, GPO, 0, PUSHPULL);enableInterrupts();while (TRUE){gpio_toggle(P20_8);systick_delay_ms(STM0, 100);} }#pragma section all restore #include "headfile.h" #pragma section all "cpu1_dsram"void core1_main(void) {disableInterrupts();IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());//用戶在此處調(diào)用各種初始化函數(shù)等//雙核的使用其實(shí)很簡(jiǎn)單,就是在兩個(gè)main中編寫不用的程序即可//本例程使用核心0 閃爍P20_8的LED 核心1閃爍P20_9的LEDgpio_init(P20_9, GPO, 0, PUSHPULL);enableInterrupts();while (TRUE){//用戶在此處編寫任務(wù)代碼gpio_toggle(P20_9);systick_delay_ms(STM1, 100);} }#pragma section all restoreGPIO初始化
//------------------------------------------------------------------------------------------------------------------- // @brief GPIO初始化 // @param pin 選擇的引腳 (可選擇范圍由 common.h 內(nèi)PIN_enum枚舉值確定) // @param dir 引腳的方向 輸出:GPO 輸入:GPI // @param dat 引腳初始化時(shí)設(shè)置的電平狀態(tài),輸出時(shí)有效 0:低電平 1:高電平 // @param pinmode 引腳配置(可設(shè)置參數(shù)由zf_gpio.h文件內(nèi)GPIOMODE_enum枚舉值確定) // @return void // Sample usage: gpio_init(P00_0, GPO, 1, PUSHPULL);//P00_0初始化為GPIO功能、輸出模式、輸出高電平、推挽輸出 // @note 需要特別注意P20_2是不能用于輸出的,僅僅只有輸入的功能 //------------------------------------------------------------------------------------------------------------------- void gpio_init(PIN_enum pin, GPIODIR_enum dir, uint8 dat, GPIOMODE_enum pinmode) {IfxPort_Mode port_mode;if(dir == GPI){switch(pinmode){case NO_PULL: port_mode = IfxPort_Mode_inputNoPullDevice; break;case PULLUP: port_mode = IfxPort_Mode_inputPullUp; break;case PULLDOWN: port_mode = IfxPort_Mode_inputPullDown; break;default: port_mode = IfxPort_Mode_inputPullUp; break;}}else{switch(pinmode){case OPENDRAIN: port_mode = IfxPort_Mode_outputOpenDrainGeneral; break;//開漏輸出default: port_mode = IfxPort_Mode_outputPushPullGeneral; break;//默認(rèn)為推挽輸}}IfxPort_setPinMode(get_port(pin), pin&0x1f, port_mode);IfxPort_setPinPadDriver(get_port(pin), pin&0x1f, IfxPort_PadDriver_cmosAutomotiveSpeed1);if(dir == GPO){if(dat) IfxPort_setPinHigh(get_port(pin), pin&0x1f);else IfxPort_setPinLow(get_port(pin), pin&0x1f);}}GPIO 翻轉(zhuǎn)
//------------------------------------------------------------------------------------------------------------------- // @brief GPIO 翻轉(zhuǎn) // @param pin 選擇的引腳 (可選擇范圍由 common.h 內(nèi)PIN_enum枚舉值確定) // @return void // Sample usage: gpio_toggle(P00_0);//P00_0引腳電平翻轉(zhuǎn) //------------------------------------------------------------------------------------------------------------------- void gpio_toggle(PIN_enum pin) {IfxPort_togglePin(get_port(pin), pin&0x1f); }使用ILLD進(jìn)行軟件FFT計(jì)算
#include "headfile.h" #include "SysSe/Math/Ifx_FftF32.h" #pragma section all "cpu0_dsram"#define SAMPLE_FREQUENCY 100 //定義采樣頻率 #define SIZE_N 2000 //定義采集數(shù)量cfloat32 fft_in[SIZE_N]; cfloat32 fft_out[SIZE_N]; uint32 use_time;//本例程專門配套編寫了matlab代碼 //對(duì)函數(shù)y = 1024*(cos(3*pi*x))+512*(cos(7*pi*x)+pi/2)+2047做FFT運(yùn)算 //然后繪制出幅頻圖像,可以在工程目錄下找到FFT.m文件,使用matlab打開并運(yùn)行可以看到繪制的幅頻圖像int core0_main(void) {int i;double x1, x2;get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等enableInterrupts();for (i=0; i<SIZE_N; i++) //生成輸入信號(hào){//函數(shù)為y = 1024*(cos(3*pi*x))+512*(cos(7*pi*x)+pi/2)+2047//計(jì)算xx1 = 3 * IFX_PI * (double)i / SAMPLE_FREQUENCY;x2 = (7 * IFX_PI * (double)i / SAMPLE_FREQUENCY) + (IFX_PI / 2);//代入x計(jì)算yfft_in[i].real =(float32)(1024 * cosf(x1) + 512 * cosf(x2) + 2047);fft_in[i].imag =0.0;}while (TRUE){systick_start(STM0); //開始計(jì)時(shí)Ifx_FftF32_radix2(fft_out, fft_in, SIZE_N); //進(jìn)行FFT運(yùn)算//Ifx_FftF32_radix2I 為IFT(FFT逆變換)運(yùn)算use_time = systick_getval_us(STM0); //獲取計(jì)時(shí)時(shí)間//將結(jié)果通過串口打印,可以先學(xué)習(xí)printf例程,了解如何使用printfprintf("use_time: %ldus\n", use_time); //打印fft一次耗時(shí)多久} }#pragma section all restore指定變量或代碼位置
RAM
RAM :隨機(jī)存取存儲(chǔ)器(random access memory,RAM)又稱作“隨機(jī)存儲(chǔ)器”。
是與CPU直接交換數(shù)據(jù)的內(nèi)部存儲(chǔ)器,也叫主存(內(nèi)存)。它可以隨時(shí)讀寫,而且速度很快,通常作為操作系統(tǒng)或其他正在運(yùn)行中的程序的臨時(shí)數(shù)據(jù)存儲(chǔ)媒介。
在計(jì)算機(jī)的組成結(jié)構(gòu)中,有一個(gè)很重要的部分,就是存儲(chǔ)器。存儲(chǔ)器是用來存儲(chǔ)程序和數(shù)據(jù)的部件,對(duì)于計(jì)算機(jī)來說,有了存儲(chǔ)器,才有記憶功能,才能保證正常工作。存儲(chǔ)器的種類很多,按其用途可分為主存儲(chǔ)器和輔助存儲(chǔ)器[或者內(nèi)存儲(chǔ)器和外存儲(chǔ)器,主存儲(chǔ)器簡(jiǎn)稱內(nèi)存。內(nèi)存在電腦中起著舉足輕重的作用。內(nèi)存一般采用半導(dǎo)體存儲(chǔ)單元。
因?yàn)镽AM是內(nèi)存其中最重要的存儲(chǔ)器,所以通常我們直接稱之為內(nèi)存。
#include "headfile.h"//如果是新手可以先不學(xué)習(xí)本例程,本例程主要針對(duì)單片機(jī)基礎(chǔ)較好的同學(xué),想自己優(yōu)化RAM分配提高性能的同學(xué)參考學(xué)習(xí) //學(xué)習(xí)的時(shí)候請(qǐng)從上往下認(rèn)真閱讀。//在TC264中的兩個(gè)核心,實(shí)際上他們的流水線數(shù)量是不一樣的,CPU0是一級(jí)流水線,CPU1是三級(jí)流水線,因此CPU1更適合做運(yùn)算,速度會(huì)比CPU0快一些。//TC264D單片機(jī)有如下幾個(gè)RAM可供用戶使用 //CPU0 psram 程序RAM 大小為16KB //CPU0 dsram 數(shù)據(jù)RAM 大小為72KB//CPU1 psram 程序RAM 大小為32KB //CPU1 dsram 數(shù)據(jù)RAM 大小為120KB//TC264D中兩個(gè)核心都有自己的程序緩存 //CPU0 Cache大小為8KB //CPU1 Cache大小為16KB//程序RAM用來放代碼,將代碼放在RAM中,可以提高執(zhí)行速度,特別是當(dāng)周期運(yùn)行的代碼大小超過了cache之后效果比較顯著。 //數(shù)據(jù)RAM用來放變量,任意CPU都可以訪問dsram0和dsram1,也就是說CPU0可以訪問dsram1,這種行為叫做跨核訪問,帶來的問題就是訪問延遲有所增大 //最好的是CPU0訪問dsram0,CPU1訪問dsram1,這樣速度最快。 //默認(rèn)情況下定義的全局變量都是保存在dsram1中的,這就會(huì)導(dǎo)致在CPU0中跑的代碼對(duì)RAM讀取會(huì)有一定的延遲//那么接下來我們就要學(xué)習(xí)如何指定變量存放位置//使用#pragma section all "cpu0_dsram" 和 #pragma section all restore可以將變量放在cpu0_dsram //我們只需要將變量定義放在上面兩句話中間即可,使用示例如下 #pragma section all "cpu0_dsram" uint8 test_arry[5]; //將變量放在cpu0_dsram區(qū)域內(nèi) //如果將cpu0_dsram改為cpu1_dsram 則變量放在cpu1_dsram區(qū)域內(nèi) //我們建議程序由哪個(gè)CPU執(zhí)行,則將所使用的變量放置在哪個(gè)區(qū)域內(nèi),默認(rèn)不指定的情況下變量被放置在cpu1_dsram區(qū)域 #pragma section all restore//使用#pragma section all "cpu0_psram" 和 #pragma section all restore可以將函數(shù)加載到cpu0_psram //我們只需要將函數(shù)定義放在上面兩句話中間即可,使用示例如下 #pragma section all "cpu0_psram" void delay_tset(void) //將函數(shù)加載到cpu0_psram區(qū)域內(nèi)執(zhí)行 {int i;i = 999;while(i--); } //如果將cpu0_psram改為cpu1_psram 則函數(shù)加載到cpu1_psram區(qū)域內(nèi) //我們建議程序由哪個(gè)CPU執(zhí)行,則將函數(shù)加載到在哪個(gè)區(qū)域內(nèi),默認(rèn)不指定的情況下,程序都是從flash加載并執(zhí)行 //通常我們都不需要將函數(shù)放在RAM運(yùn)行,一般在周期執(zhí)行的程序大小超過了cache后,會(huì)出現(xiàn)程序執(zhí)行速度降低,這個(gè)時(shí)候我們就可以將部分代碼放入RAM執(zhí)行,可以提高運(yùn)算速度 #pragma section all restore//如果在寫代碼的時(shí)候忘記了上面的使用方式,可以從Libraries\Doc文件夾內(nèi)找到version.txt,打開后可以看到上面的使用示例int core0_main(void) {get_clk();//獲取時(shí)鐘頻率 務(wù)必保留test_arry[0] = 0;delay_tset();enableInterrupts();while (TRUE){//如果是新手可以先不學(xué)習(xí)本例程,本例程主要針對(duì)單片機(jī)基礎(chǔ)較好的同學(xué),想自己優(yōu)化RAM分配提高性能的同學(xué)參考學(xué)習(xí)//如果是移植代碼請(qǐng)務(wù)必從最新版本的庫,提取LSL文件替換到自己的工程//學(xué)習(xí)的時(shí)候請(qǐng)從上往下認(rèn)真閱讀。} }使用CPU1處理中斷
#include "headfile.h" #pragma section all "cpu0_dsram" //將本語句與#pragma section all restore語句之間的全局變量都放在CPU0的RAM中//工程導(dǎo)入到軟件之后,應(yīng)該選中工程然后點(diǎn)擊refresh刷新一下之后再編譯 //工程默認(rèn)設(shè)置為關(guān)閉優(yōu)化,可以自己右擊工程選擇properties->C/C++ Build->Setting //然后在右側(cè)的窗口中找到C/C++ Compiler->Optimization->Optimization level處設(shè)置優(yōu)化等級(jí) //一般默認(rèn)新建立的工程都會(huì)默認(rèn)開2級(jí)優(yōu)化,因此大家也可以設(shè)置為2級(jí)優(yōu)化//對(duì)于TC系列默認(rèn)是不支持中斷嵌套的,希望支持中斷嵌套需要在中斷內(nèi)使用enableInterrupts();來開啟中斷嵌套 //簡(jiǎn)單點(diǎn)說實(shí)際上進(jìn)入中斷后TC系列的硬件自動(dòng)調(diào)用了disableInterrupts();來拒絕響應(yīng)任何的中斷,因?yàn)樾枰覀冏约菏謩?dòng)調(diào)用enableInterrupts();來開啟中斷的響應(yīng)。 int core0_main(void) {disableInterrupts();get_clk();//獲取時(shí)鐘頻率 務(wù)必保留//用戶在此處調(diào)用各種初始化函數(shù)等//特別注意通道2 與 通道3都被攝像頭占用,由于中斷共用的關(guān)系,因此通道6 與 通道7也不能使用//TC264的外部中斷不像K60單片機(jī)那樣所有IO都支持,TC264只有部分支持具體可以查看zf_eru.h中ERU_PIN_enum枚舉定義eru_init(ERU_CH0_REQ0_P15_4, RISING); //ERU通道0 使用P15_4引腳 上升沿中斷eru_init(ERU_CH4_REQ13_P15_5, RISING); //ERU通道4 使用P15_5引腳 上升沿中斷//通道0與4共用中斷,中斷內(nèi)通過標(biāo)志位判斷eru_init(ERU_CH1_REQ10_P14_3, RISING); //ERU通道1 使用P14_3引腳 上升沿中斷eru_init(ERU_CH5_REQ1_P15_8, RISING); //ERU通道5 使用P15_8引腳 上升沿中斷//通道1與5共用中斷,中斷內(nèi)通過標(biāo)志位判斷//中斷函數(shù)在isr.c中//函數(shù)名稱分別為eru_ch0_ch4_isr 與 eru_ch1_ch5_isr//中斷相關(guān)的配置參數(shù)在isr_config.h內(nèi)//可配置參數(shù)有 ERU_CH0_CH4_INT_SERVICE 和 ERU_CH0_CH4_INT_PRIO//ERU_CH0_CH4_INT_SERVICE 中斷服務(wù)者,表示改中斷由誰處理,0:CPU0 1:CPU1 3:DMA 不可設(shè)置為其他值//ERU_CH0_CH4_INT_PRIO 中斷優(yōu)先級(jí) 優(yōu)先級(jí)范圍1-255 越大優(yōu)先級(jí)越高 與平時(shí)使用的單片機(jī)不一樣//本例程ERU_CH0_CH4_INT_SERVICE默認(rèn)配置為1了 也就是由CPU1處理//ERU其他中斷也是同理//需要特備注意的是 不可以有優(yōu)先級(jí)相同的中斷函數(shù) 每個(gè)中斷的優(yōu)先級(jí)都必須是不一樣的enableInterrupts();while (TRUE){//在isr.c的中斷函數(shù),函數(shù)定義的第二個(gè)參數(shù)固定為0,請(qǐng)不要更改,即使你用CPU1處理中斷也不要更改,需要CPU1處理中斷只需要在isr_config.h內(nèi)修改對(duì)應(yīng)的宏定義即可//程序運(yùn)行之后,使用杜邦線將P15_4、P15_5、P14_3、P15_8連接到GND,然后在斷開,在連接如此往復(fù)//在FSS窗口會(huì)看到對(duì)應(yīng)的提示信息} }#pragma section all restoreeru初始化(gpio中斷)
//------------------------------------------------------------------------------------------------------------------- // @brief eru初始化(gpio中斷) // @param eru_pin 設(shè)置eru通道及引腳 // @param trigger 設(shè)置觸發(fā)方式 // @return void // Sample usage: eru_init(ERU_CH0_REQ0_P15_4, RISING);//eru通道0 使用P10_7引腳,上升沿觸發(fā)中斷 //------------------------------------------------------------------------------------------------------------------- void eru_init(ERU_PIN_enum eru_pin, TRIGGER_enum trigger) {boolean interrupt_state = disableInterrupts();IfxScu_Req_In *reqPin;reqPin = eru_mux(eru_pin);IfxScuEru_initReqPin(reqPin, IfxPort_InputMode_pullUp);IfxScuEru_InputChannel inputChannel = (IfxScuEru_InputChannel)reqPin->channelId;IfxScuEru_InputNodePointer triggerSelect = (IfxScuEru_InputNodePointer)(eru_pin/3);IfxScuEru_OutputChannel outputChannel = (IfxScuEru_OutputChannel)(eru_pin/3);switch(trigger){case RISING:{IfxScuEru_disableFallingEdgeDetection(inputChannel);IfxScuEru_enableRisingEdgeDetection(inputChannel);}break;case FALLING:{IfxScuEru_enableFallingEdgeDetection(inputChannel);IfxScuEru_disableRisingEdgeDetection(inputChannel);}break;case BOTH:{IfxScuEru_enableFallingEdgeDetection(inputChannel);IfxScuEru_enableRisingEdgeDetection(inputChannel);}break;default: ZF_ASSERT(FALSE);}IfxScuEru_enableTriggerPulse(inputChannel);IfxScuEru_connectTrigger(inputChannel, triggerSelect);IfxScuEru_setFlagPatternDetection(outputChannel, inputChannel, TRUE);IfxScuEru_enablePatternDetectionTrigger(outputChannel);IfxScuEru_setInterruptGatingPattern(outputChannel, IfxScuEru_InterruptGatingPattern_alwaysActive);volatile Ifx_SRC_SRCR *src = &MODULE_SRC.SCU.SCU.ERU[(int)outputChannel % 4];IfxSrc_Tos eru_service;uint8 eru_priority;switch((eru_pin/3)%4){case 0:{eru_service = (IfxSrc_Tos)ERU_CH0_CH4_INT_SERVICE;eru_priority = ERU_CH0_CH4_INT_PRIO;}break;case 1:{eru_service = (IfxSrc_Tos)ERU_CH1_CH5_INT_SERVICE;eru_priority = ERU_CH1_CH5_INT_PRIO;}break;case 2:{eru_service = (IfxSrc_Tos)ERU_CH2_CH6_INT_SERVICE;eru_priority = ERU_CH2_CH6_INT_PRIO;}break;case 3:{eru_service = (IfxSrc_Tos)ERU_CH3_CH7_INT_SERVICE;eru_priority = ERU_CH3_CH7_INT_PRIO;}break;} #pragma warning 507IfxSrc_init(src, eru_service, eru_priority); #pragma warning defaultIfxSrc_enable(src);restoreInterrupts(interrupt_state); }電磁尋跡文件閱讀
#include "headfile.h" #define ADC_LEFT_CHANNEL ADC1_CH3_B14//定義左電感通道 #define ADC_RIGHT_CHANNEL ADC1_CH4_B15//定義右電感通道 uint8 ad_left; uint8 ad_right; int16 ad_sum; int16 ad_diff; int16 position; int main(void) { DisableGlobalIRQ(); board_init();//務(wù)必保留,本函數(shù)用于初始化MPU 時(shí)鐘 調(diào)試串口 adc_init(ADC_1,ADC_LEFT_CHANNEL,ADC_8BIT);//初始化B14引腳為ADC功能,分辨率為8位 adc_init(ADC_1,ADC_RIGHT_CHANNEL,ADC_8BIT);//初始化B15引腳為ADC功能,分辨率為8位 EnableGlobalIRQ(0); while (1) { ad_left = adc_mean_filter(ADC_1,ADC_LEFT_CHANNEL,5);//采集左電感數(shù)值 采集5次求平均 ad_right = adc_mean_filter(ADC_1,ADC_RIGHT_CHANNEL,5);//采集右電感數(shù)值 采集5次求平均 ad_sum = ad_left + ad_right;//計(jì)算電感之和 ad_diff = (int16)ad_left - ad_right;//計(jì)算電感之差 if(ad_sum>30)//邊界保護(hù) { //方法一 position = (ad_diff*100)/(ad_sum+1);//計(jì)算差比和數(shù)值 并放大一百倍 //方法二 position = (ad_diff<<7)/(ad_sum+1); //計(jì)算差比和數(shù)值 并放大128倍 systick_delay_ms(5);//延時(shí)5ms } } }編程要點(diǎn)
一
對(duì)于電磁尋跡通常8位adc分辨率足夠使用,因此示例代碼中初始化adc時(shí)選擇了8位的分辨率,因此ad_left與ad_right定義的是8位無符號(hào)類型。
在前面的差比和計(jì)算中我們已經(jīng)看到了計(jì)算出來的結(jié)果是有正有負(fù)的,因此position定義的是有符號(hào)16位類型,需要注意的是在計(jì)算差的時(shí)候切記進(jìn)行強(qiáng)制轉(zhuǎn)換為有符號(hào)之后再進(jìn)行計(jì)算,也可以直接將ad_left與ad_right定義為有符號(hào),但是就需要定義為有符號(hào)16位類型,否則就可能無法存儲(chǔ)adc采集函數(shù)返回的數(shù)值,因?yàn)?位adc分辨率返回的數(shù)值范圍是0-255。
二
程序當(dāng)中有做邊界保護(hù),為什么要做邊界保護(hù)呢?首先我們來假設(shè)一下車模在運(yùn)行的過程中由于打滑或者彎道較急,導(dǎo)致導(dǎo)致電感的位置偏離賽道較多,從而導(dǎo)致兩個(gè)電感的值都比較小。例如電感1為10,電感2為15,那么差比和計(jì)算出來后結(jié)果等于-0.2,實(shí)際上車模位置已經(jīng)偏離賽道較大而計(jì)算出來的結(jié)果卻偏小,因此我們采用電感的和值進(jìn)行一定的限制,如果小于一定的值則使用保留上次的結(jié)果,不計(jì)算也就不會(huì)改變position的值也就是保留了上次的結(jié)果。
邊界保護(hù)處理算法:
邊界保護(hù)的和值的確定可以采用將車模從賽道中心往任意一邊遠(yuǎn)離,然后觀察計(jì)算出來的position,position應(yīng)該是逐漸變大然后慢慢變小,在從大變小的轉(zhuǎn)折點(diǎn)記錄下此時(shí)的和值,然后將此和值設(shè)置為邊界保護(hù)來使用,根據(jù)實(shí)際的運(yùn)行情況可以在此基礎(chǔ)上進(jìn)行調(diào)整。
三
可以看到程序中的差比和計(jì)算公式稍微有一點(diǎn)不一樣,為了避免除數(shù)為0,因此和值固定加一了,然后由于有邊界保護(hù)的原因?qū)嶋H上和值不可能為0的,主要在還沒有引入邊界保護(hù)時(shí)使用。
四
程序中我們可以看到差比和有兩個(gè)計(jì)算公式,區(qū)別在于一個(gè)放大了100倍,一個(gè)放大了128倍,首先為啥我們要對(duì)結(jié)果進(jìn)行放大呢,在最開始的時(shí)候我們已經(jīng)看見了,計(jì)算出來的結(jié)果都是小于1的,從公式原理上我們也可以看出來,差比和計(jì)算出來的結(jié)果只能是-1至1,為了直接保存結(jié)果我們就只能使用float變量去保存結(jié)果,為了提高單片機(jī)的運(yùn)算速度因此我們先對(duì)差進(jìn)行了放大,然后直接使用整數(shù)類型運(yùn)算,將結(jié)果變換為-100至100。為什么寫了兩種放大方法呢,首先第一種因?yàn)槭欠糯?00倍便于思考的時(shí)候計(jì)算簡(jiǎn)單,但是由于需要使用乘法單片機(jī)運(yùn)算速度會(huì)稍微慢一點(diǎn),因此我們還可以采用環(huán)移的方式來放大,左環(huán)移7位也就是放大了128倍比較接近100。通過這樣的方法可以進(jìn)一步的降級(jí)運(yùn)算量,提高運(yùn)算速度。需要特別注意,由于計(jì)算的過程中都是使用的整數(shù),不論是使用左環(huán)移還是乘法進(jìn)行放大時(shí),務(wù)必先放大之后再除,否則會(huì)出現(xiàn)1/2*100=0的結(jié)果。由于是整數(shù)類型的運(yùn)算1/2是等于0的,所以會(huì)出現(xiàn)錯(cuò)誤的結(jié)果。
五
對(duì)于電感采集與偏差計(jì)算實(shí)際上并不是放在主循環(huán)內(nèi)一直運(yùn)行的,一般都是將這部分代碼和舵機(jī)PD控制代碼一起放在pit周期中斷內(nèi)運(yùn)行的。至此通過電感來計(jì)算車模的位置已經(jīng)結(jié)束了,當(dāng)然這僅僅是一個(gè)初級(jí)的辦法供參考學(xué)習(xí),其他方法還需要自己一步一步探索。根據(jù)計(jì)算出來的位置信息就可以對(duì)車模的轉(zhuǎn)向和速度進(jìn)行控制了,這樣就可以實(shí)現(xiàn)讓車模跟隨賽道前進(jìn),實(shí)現(xiàn)尋跡的效果。
智能車競(jìng)賽線上培訓(xùn)
PWM波形如何生成
PWM簡(jiǎn)介
脈沖寬度調(diào)制(Pulse Width Modulation,簡(jiǎn)稱PWM)是一種對(duì)模擬信號(hào)電平進(jìn)行數(shù)字編碼的方法。
通過高分辨率計(jì)數(shù)器的使用,用方波不同的占空比用來對(duì)一個(gè)具體模擬信號(hào)的電平進(jìn)行編碼。
PWM波----周期不變,占空比可調(diào)。
pwm的頻率:是指1秒鐘內(nèi)信號(hào)從高電平到低電平再回到高電平的次數(shù)(一個(gè)周期),也就是說一秒鐘PWM有多少個(gè)周期。
單位: Hz
表示方式: 50Hz 100Hz
pwm的周期:T=1/f
占空比:是一個(gè)脈沖周期內(nèi),高電平的時(shí)間與整個(gè)周期時(shí)間的比例
單位: % (0%-100%)
表示方式:20%
定時(shí)器簡(jiǎn)介
單片機(jī)中的定時(shí)器和計(jì)數(shù)器其實(shí)是同一個(gè)物理的電子元件,只不過計(jì)數(shù)器記錄的是單片機(jī)外部 發(fā)生的事情(接受的是外部脈沖),而定時(shí)器則是由單片機(jī)自身提供的一個(gè)非常穩(wěn)定的計(jì)數(shù)器,這個(gè)穩(wěn)定的計(jì)數(shù)器就是晶振部件產(chǎn)生穩(wěn)定的時(shí)鐘信號(hào)觸發(fā)計(jì)數(shù)器而得來。
TC264時(shí)鐘信號(hào)簡(jiǎn)介
GTM和ATOM模塊說明
它包含具有不同功能子模塊的模塊框架。這些子模塊可以以可配置的方式組合以形成一個(gè)復(fù)雜的計(jì)時(shí)器模塊,該模塊為一個(gè)應(yīng)用程序域中的不同應(yīng)用程序域和不同類提供服務(wù)。 由于具有可擴(kuò)展性和可配置性,因此將計(jì)時(shí)器稱為通用計(jì)時(shí)器。
TC264 GTM時(shí)鐘信號(hào)
CMU產(chǎn)生3個(gè)子模塊
TC264 GTM ATOM介紹
連接到ARU的定時(shí)器輸出模塊 (ATOM)可以連接到ARU,因此無需CPU的干預(yù)即可生成復(fù)雜的輸出信號(hào)。
典型地,通過ARU連接通過例如連接到ARU的子模塊提供輸出信號(hào)特性。 MCS,DPLL或PSM。
每個(gè)ATOM子模塊包含八個(gè)輸出通道, 它們可以在幾種可配置的操作模式下彼此獨(dú)立地操作。
更新占空比和周期的方式,有兩種同步更新和異步更新 。我們一般用同步更新。占空比、周期的同步變化意味著在前一個(gè)周期結(jié)束之后, 占空比或周期持續(xù)時(shí)間發(fā)生變化。
同步通信和異步通信
首先是兩者的不同
- 同步通信要求接收端時(shí)鐘頻率和發(fā)送端時(shí)鐘頻率一致,發(fā)送端發(fā)送連續(xù)的比特流;異步通信時(shí)不要求接收端時(shí)鐘和發(fā)送端時(shí)鐘同步,發(fā)送端發(fā)送完一個(gè)字節(jié)后,可經(jīng)過任意長(zhǎng)的時(shí)間間隔再發(fā)送下一個(gè)字節(jié)。
- 同步通信效率高;異步通信效率較低。
- 同步通信較復(fù)雜,雙方時(shí)鐘的允許誤差較小;異步通信簡(jiǎn)單,雙方時(shí)鐘可允許一定誤差。
- 同步通信可用于點(diǎn)對(duì)多點(diǎn);異步通信只適用于點(diǎn)對(duì)點(diǎn)。
異步通信
- 異步通信中的接收方并不知道數(shù)據(jù)什么時(shí)候會(huì)到達(dá),收發(fā)雙方可以有各自自己的時(shí)鐘。發(fā)送方發(fā)送的時(shí)間間隔可以不均,接收方是在數(shù)據(jù)的起始位和停止位的幫助下實(shí)現(xiàn)信息同步的。這種傳輸通常是很小的分組,比如一個(gè)字符為一組,為這個(gè)組配備起始位和結(jié)束位。所以這種傳輸方式的效率是比較低的,畢竟額外加入了很多的輔助位作為負(fù)載,常用在低速的傳輸中。
- 以RS232協(xié)議規(guī)定為例,異步通信一個(gè)字符一個(gè)字符地傳輸,每個(gè)字符一位一位地傳輸,并且傳輸一個(gè)字符時(shí),總是以“起始位”開始(低電平,邏輯值0),以“停止位”結(jié)束,字符之間沒有固定的時(shí)間間隔要求。字符數(shù)據(jù)本身由5~8位數(shù)據(jù)位組成,接著字符后面是一位校驗(yàn)位(也可以沒有校驗(yàn)位),最后是一位或一位半或二位停止位,停止位后面是不定長(zhǎng)的空閑位。停止位和空閑位都規(guī)定為高電平(邏輯值1),這樣就保證起始位開始處一定有一個(gè)下跳沿。
- 舉個(gè)例子,我們的鍵盤按下一個(gè)按鍵,發(fā)出一個(gè)字符信號(hào),異步傳輸機(jī)制就會(huì)為它加上前后的輔助同步信息,幫助接收方識(shí)別到我們按下了哪一個(gè)按鍵。因?yàn)槲覀兦脫翩I盤的節(jié)奏不固定,所以異步是一種很適合的方式。
同步通信
- 同步通信中雙方使用頻率一致的時(shí)鐘,它的分組相比異步則大得多,稱為一個(gè)數(shù)據(jù)幀,通過獨(dú)特的bit串作為啟停標(biāo)識(shí)。發(fā)送方要以固定的節(jié)奏去發(fā)送數(shù)據(jù),而接收方要時(shí)刻做好接收數(shù)據(jù)的準(zhǔn)備,識(shí)別到前導(dǎo)碼后馬上要開始接收數(shù)據(jù)了。同步這種方式中因?yàn)榉纸M很大,很長(zhǎng)一段數(shù)據(jù)才會(huì)有額外的輔助位負(fù)載,所以效率更高,更加適合對(duì)速度要求高的傳輸,當(dāng)然這種通信對(duì)時(shí)序的要求也更高。
- 同步通信是一種連續(xù)串行傳送數(shù)據(jù)的通信方式,一次通信只傳送一幀信息,由同步字符、數(shù)據(jù)字符和校驗(yàn)字符(CRC)組成。
中斷有兩個(gè):
在CN0等于CM1時(shí),觸發(fā)中斷。
在CN0等于CM0時(shí),觸發(fā)中斷。
模數(shù)轉(zhuǎn)換
ADC基本性能
TC26x提供了一系列模擬輸入通道,這些通道使用逐次逼近寄存器(SAR) 原理連接到模擬/數(shù)字轉(zhuǎn)換器的群集,以將模擬輸入值(電壓)轉(zhuǎn)換為離散的數(shù)字值。
- 最多4個(gè)獨(dú)立的轉(zhuǎn)換器,每個(gè)轉(zhuǎn)換器最多16個(gè)模擬輸入通道。
- 轉(zhuǎn)換時(shí)間低于1 μs(取決于結(jié)果寬度和采樣時(shí)間)
- 靈活的來源選擇和仲裁
- 可編程的任意轉(zhuǎn)換序列(單個(gè)或重復(fù))
- 每組中可配置的自動(dòng)掃描轉(zhuǎn)換(單個(gè)或重復(fù))
- 在后臺(tái)(所有轉(zhuǎn)換器)中可配置的自動(dòng)掃描轉(zhuǎn)換(單個(gè)或重復(fù))
- 8/10/12位的可選結(jié)果寬度
- 獨(dú)立的結(jié)果寄存器
請(qǐng)求控制單元
TC275的ADC模塊共提供3種請(qǐng)求源,即順序請(qǐng)求源、掃描請(qǐng)求源和后臺(tái)請(qǐng)求源。
每個(gè)通道可以放到順序請(qǐng)求源或者掃描請(qǐng)求源中,如果某通道既沒有在順序請(qǐng)求源,也沒有在掃描請(qǐng)求源中,那么該通道被放到后臺(tái)請(qǐng)求源中。
轉(zhuǎn)換控制單元
主要設(shè)置采樣時(shí)間、 轉(zhuǎn)換精度和參考電壓等參數(shù)。
采樣過程
串口通信
通訊概念簡(jiǎn)介
同步通信
發(fā)送端在發(fā)送串行數(shù)據(jù)的同時(shí),提供一個(gè)時(shí)鐘信號(hào),并按照一定的約定(例如:在時(shí)鐘信號(hào)的上升沿的時(shí)候,將數(shù)據(jù)發(fā)送出去)發(fā)送數(shù)據(jù),接收端根據(jù)發(fā)送端提供的時(shí)鐘信號(hào),以及大家的約定,接收數(shù)據(jù)。
異步通信
接收方并不知道數(shù)據(jù)什么時(shí)候會(huì)到達(dá),收發(fā)雙方可以有各自自己的時(shí)鐘。發(fā)送方發(fā)送的時(shí)間間隔可以不均,接收方是在數(shù)據(jù)的起始位和停止位的幫助下實(shí)現(xiàn)信息同步的。這種傳輸通常是很小的分組。
SPI通信
SPI是串行外設(shè)接口(Serial Peripheral Interface)的縮寫,是Motorola首先在其MC68HCXX系列處理器上定義的。SPI接口主要應(yīng)用在EEPROM、FLASH、實(shí)時(shí)時(shí)鐘、AD轉(zhuǎn)換器等器件之間的通信。它在芯片中只占用四根管腳 (Pin) 用來控制以及數(shù)據(jù)傳輸, 節(jié)約了芯片的引腳數(shù)目, 同時(shí)為 PCB在布局上節(jié)省了空間. 正是出于這種簡(jiǎn)單易用的特性, 現(xiàn)在越來越多的芯片上都集成了 SPI技術(shù)。
UART通信
通用異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter,通常稱作UART) 是一種串行異步收發(fā)協(xié)議,應(yīng)用十分廣泛。UART工作原理是將數(shù)據(jù)的二進(jìn)制位一位一位的進(jìn)行傳輸。在UART通訊協(xié)議中信號(hào)線上的狀態(tài)位高電平代表’1’低電平代表’0’。當(dāng)然兩個(gè)設(shè)備使用UART串口通訊時(shí),必須先約定好傳輸速率和一些數(shù)據(jù)位。
ASCLIN模塊簡(jiǎn)介
ASCLIN模塊的主要目的是僅使用數(shù)據(jù)輸入 (RX),數(shù)據(jù)輸出(TX)信號(hào)提供與外部設(shè)備的異步串行通信。 該模塊的重點(diǎn)是快速靈活的通信:使用LIN協(xié)議的快速點(diǎn)對(duì)點(diǎn)或主機(jī)對(duì)多從機(jī)通信。此外,該模塊支持同步SPI通信。
基本工作過程說明
如何讀取編碼器信號(hào)
簡(jiǎn)述增量編碼
編碼器(encoder)
是將信號(hào)(如比特流)或數(shù)據(jù)進(jìn)行編制、轉(zhuǎn)換為可用以通訊、傳輸和存儲(chǔ)的信號(hào)形式的設(shè)備。編碼器把角位移或直線位移轉(zhuǎn)換成電信號(hào),前者稱為碼盤,后者稱為碼尺。 按照工作原理編碼器可分為增量式和絕對(duì)式兩類。
增量式編碼器
是將位移轉(zhuǎn)換成周期性的電信號(hào),再把這個(gè)電信號(hào)轉(zhuǎn)變成計(jì)數(shù)脈沖,用脈沖的個(gè)數(shù)表示位移的大小。
增量式的兩種信號(hào)模式
絕對(duì)式編碼器
絕對(duì)式編碼器的每一個(gè)位置對(duì)應(yīng)一個(gè)確定的數(shù)字碼,因此它的示值只與測(cè)量的起始和終止位置有關(guān),而與測(cè)量的中間過程無關(guān)。
單圈絕對(duì)式編碼器
旋轉(zhuǎn)單圈絕對(duì)式編碼器,以轉(zhuǎn)動(dòng)中測(cè)量光碼盤各道刻線,以獲取唯一的編碼,當(dāng)轉(zhuǎn)動(dòng)超過360度時(shí),編碼器又回到原點(diǎn),這樣就不符合絕對(duì)編碼唯一的原則,這樣的編碼器只能用于旋轉(zhuǎn)范圍360度以內(nèi)的測(cè)量,稱為單圈絕對(duì)式編碼器。
多圈絕對(duì)式編碼器
測(cè)量旋轉(zhuǎn)超過360度范圍,就要使用多圈絕對(duì)式編碼器。
編碼器生產(chǎn)廠家運(yùn)用鐘表齒輪機(jī)械原理,當(dāng)中心碼盤旋轉(zhuǎn)時(shí),通過齒輪傳動(dòng)另一組碼盤(或多齒輪,多組碼盤),在單圈編碼的基礎(chǔ)上再增加圈數(shù)的編碼,以擴(kuò)大編碼器的測(cè)量范圍,這樣的絕對(duì)編碼器就稱為多圈式絕對(duì)編碼器。
GPT12模塊介紹
通用定時(shí)器單元模塊GPT1和 GPT2具有非常靈活的多功能定時(shí)器結(jié)構(gòu),可用于定時(shí),事件計(jì)數(shù),脈沖寬度測(cè)量,脈沖生成,倍頻和其他目的。
它們包含五個(gè)16位定時(shí)器,這些定時(shí)器被分組到兩個(gè)定時(shí)器模塊GPT1和GPT2中。 每個(gè)塊中的每個(gè)定時(shí)器都可以在多種不同模式下獨(dú)立運(yùn)行,例如門控定時(shí)器或計(jì)數(shù)器模式,或者可以與同一塊中的另一個(gè)定時(shí)器串聯(lián)。
GPT1:T2/T3/T4功能
- 計(jì)時(shí)器模式
- 門控定時(shí)器模式
- 計(jì)數(shù)器模式
- 增量接口模式
GPT2:T5/T6功能
- 計(jì)時(shí)器模式
- 門控定時(shí)器模式
- 計(jì)數(shù)器模式
引腳說明
計(jì)數(shù)模式
增量編碼模式
總結(jié)
以上是生活随笔為你收集整理的第三周铁人战队学习总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 逻辑覆盖测试
- 下一篇: 一个-书,字 我惆怅