打印
[活动]

【G32A1465开发板】学习中断的应用

[复制链接]
43|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhjb1|  楼主 | 2024-12-19 10:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zhjb1 于 2024-12-19 11:04 编辑

八、学习中断的应用
这个实验也不复杂,我所有的实验非必须都是基于测评三、的GPIO_LCD增加内容完成。
打开PINS_LED工程,打开main.c;此时已经有了key的中断,现在的程序计数器是采用循环语句中增加完成的:
if(js>999999)js=0;else js++;
就是说while循环一次js(设定的程序计数器值)增加一个,目的是为了看程序能运行多少次宕机,当然也可以观察运行了多少个循环。在某些应用中是有意义的,但有一个致命的问题:有些代码与运行有关,时快时慢造成循环的计数值乘以时间不等于实际运行时间,这是采用系统自动中断技术是最好的方法,本实验就是为了完成此目标,很小一小步。
打开key的中断相关函数:
void KEY_IRQHandler(void){
//Get interrupt flag——中断标志
if((PINS_ReadPmInt**(PMC) & (1<<KEY1_PIN)) != 0){
  LED_On(LED_RED);
//Clear interrupt flag——清除中断标志
  PINS_ClrPinInt**Cmd(PMC, KEY1_PIN);kk=101;
}else if((PINS_ReadPmInt**(PMC) & (1<<KEY2_PIN)) != 0){
  LED_Off(LED_RED);
//Clear interrupt flag——清除中断标志
  PINS_ClrPinInt**Cmd(PMC, KEY2_PIN);kk=202;
}else{
//Clear interrupt flags for all pins in the port
  PINS_ClrPmInt**Cmd(PMC);
}
}
这里只是中断执行结果,下边看main中的中断控制函数,有两个:
//set PMC interrupt callback function
INT_SYS_InstallHandler(PMC_IRQn,&KEY_IRQHandler,(ISR_T*) 0);
//Enable PMC interrupt
INT_SYS_EnableIRQ(PMC_IRQn);
前一个是中断句柄——标注为回访函数,叫什么无所谓,知道是中断号和中断句柄声明;
后一句是中断向量允许。到此已经完成了一半。我们的目的是将程序计数器放在StsTick的中断函数中,因此也需要启动SysTick的这两个句柄增加如下两句(当然需要在项目中遍历搜寻此函数句柄的)
第一步:
对应第一句:
INT_SYS_InstallHandler(SysTick_IRQn,&SysTick_Handler,(ISR_T*) 0);
对应第二句:
INT_SYS_EnableIRQ(SysTick_IRQn);
加载key中断的附近,其实无所谓的啦,只要是系统首先的语句之后即可。
第二步:将uint32_t js;增加到g32a1xxx_int.c的前边;
extern uint32_t js;
第三步:找到void SysTick_Handler(void)函数,在里面添加:
js++;
之后更改原while中的if(js>999999)js=0;else js++;为:
if(js>999999)js=0;
去掉js++;
至此重新编译下载后计数器的值也在快速增加,并且不会随主函数延时设定的长短改变,尽管while中有定时语句,定时100mS一循环。
主函数的代码:
//main.c Main program V1.0.0 2024-03-20 Copyright (C) 2024 Geehy Semiconductor
//Includes
#include "user_config.h"
#include "board.h"
#include <stdio.h>
#include <stdbool.h>
#include "g32a1xxx_int.h"
#include "g32a1xxx_adc.h"
#include "g32a1xxx_pins.h"
//#include "osif.h"
#include "12864.h"
//G32A1465_Examples
//ADC_SoftwareConversion_Macros Macros
#define ADC_INSTANCE (0U)
static __IO uint32_t g_timingDelay;
float g_adcMaxValue = 4096;
float g_adcDifference = 3.3f;
int k=0,kk=0;
uint32_t js=0;
float adcValue;
//PINS_Led_Macros Macros
#define LED_GPIO   GPIOD
#define BLUE_LED_PIN  (0U)
#define RED_LED_PIN   (15U)
#define GREEN_LED_PIN (16U)
#define WHITE_LED_PIN (~0x00018001)//NOTE:For testing reference only!
// Start SysTick
void SysTick_Init(void){
//Update System Core Clock info
SystemCoreClockUpdate();
//SystemFrequency/1000=1ms
if(SysTick_Config(SystemCoreClock / 1000)) {while(1);}//Capture error
}
//Time in milliseconds Decrements the TimingDelay
void SysTick_Delay_ms(__IO uint32_t nTime){g_timingDelay = nTime;while (g_timingDelay != 0);}
void TimingDelay_Decrement(void){if (g_timingDelay != 0){g_timingDelay--;}}
//Key IniteruptHandler
void KEY_IRQHandler(void){
//Get interrupt flag
if((PINS_ReadPmInt**(PMC) & (1<<KEY1_PIN)) != 0){
  LED_On(LED_RED);
//Clear interrupt flag
  PINS_ClrPinInt**Cmd(PMC, KEY1_PIN);kk=101;
}else if((PINS_ReadPmInt**(PMC) & (1<<KEY2_PIN)) != 0){
  LED_Off(LED_RED);
//Clear interrupt flag
  PINS_ClrPinInt**Cmd(PMC, KEY2_PIN);kk=202;
}else{
//Clear interrupt flags for all pins in the port
  PINS_ClrPmInt**Cmd(PMC);
}
}
//ADC software conversion initialization configuration
void ADC_init(void){
ADC_CONV_CFG_T tempAdcConvCfg0;
ADC_AVG_CFG_T tempAdcAverCfg0;
ADC_CALIBRATION_T tempAdcCalibration0;
//Reset adc module
ADC_Reset(ADC_INSTANCE);
//Call default configuration
ADC_ConfigConverterStruct(&tempAdcConvCfg0);
tempAdcConvCfg0.clockDivision = ADC_CLK_DIVISION_4;
tempAdcConvCfg0.resolution = ADC_RESOLUTION_RATIO_12BIT;
//Call default configuration
ADC_ConfigHwAverageStruct(&tempAdcAverCfg0);
tempAdcAverCfg0.hwAvgEnable = true;
tempAdcAverCfg0.hwAverage = ADC_HW_AVERAGE_32;
//Call default configuration
ADC_ConfigUserCalibrationStruct(&tempAdcCalibration0);
tempAdcCalibration0.userGain = ADC_DEFAULT_SAMPLE_TIME;
tempAdcCalibration0.userOffset = 20000u;
//Set software pre triggering
ADC_SetSwPretrigger(ADC_INSTANCE,ADC_SW_PRE_TRIGGER_0);
//Initialize ADC based on configuration values
ADC_ConfigConverter(ADC_INSTANCE,&tempAdcConvCfg0);
//Initialize ADC hardware averaging function based on configuration values
ADC_ConfigHwAverage(ADC_INSTANCE,&tempAdcAverCfg0);
//Enable calibration function
ADC_ConfigUserCalibration(ADC_INSTANCE,&tempAdcCalibration0);
//Verify ADC
ADC_AutoCalibration(ADC_INSTANCE);
}
//Read ADC value
float ADC_readValue(void){
uint16_t partAdcValue;
ADC_CHAN_CONFIG_T tempAdcChanCfg0;
//Call default configuration
ADC_ConfigChanStruct(&tempAdcChanCfg0);
tempAdcChanCfg0.interruptEnable = false;
tempAdcChanCfg0.channel = ADC_INPUT_CHANNEL_EXT12;
//Trigger using software
ADC_ConfigChan(ADC_INSTANCE, 0u, &tempAdcChanCfg0);
//waiting for conversion to complete
ADC_WaitConvDone(ADC_INSTANCE);
//Obtain conversion results
ADC_ReadChanResult(ADC_INSTANCE, 0u, &partAdcValue);
return (float)partAdcValue;
}
void PINS_Led_Init(){
//Enable Clock to Port D
CLOCK_SYS_ConfigModuleClock(PMD_CLK, NULL);
//Set pin mode
PINS_SetMuxModeSel(LED_RED_PORT_BASE, LED_RED_PIN, PM_MUX_AS_GPIO);
PINS_SetMuxModeSel(LED_GREEN_PORT_BASE, LED_GREEN_PIN, PM_MUX_AS_GPIO);
PINS_SetMuxModeSel(LED_BLUE_PORT_BASE, LED_BLUE_PIN, PM_MUX_AS_GPIO);
//Set pin interrupt
PINS_SetPinIntSel(LED_RED_PORT_BASE, LED_RED_PIN, PM_DMA_INT_DISABLED);
PINS_SetPinIntSel(LED_GREEN_PORT_BASE, LED_GREEN_PIN, PM_DMA_INT_DISABLED);
PINS_SetPinIntSel(LED_BLUE_PORT_BASE, LED_BLUE_PIN, PM_DMA_INT_DISABLED);
//GPIO Initialization
PINS_SetPins(LED_RED_GPIO_BASE, 1U << LED_RED_PIN);
PINS_SetPins(LED_GREEN_GPIO_BASE, 1U << LED_GREEN_PIN);
PINS_SetPins(LED_BLUE_GPIO_BASE, 1U << LED_BLUE_PIN);
//Set pin as output
PINS_SetPinDir(LED_RED_GPIO_BASE, LED_RED_PIN, 1U);
PINS_SetPinDir(LED_GREEN_GPIO_BASE, LED_GREEN_PIN, 1U);
PINS_SetPinDir(LED_BLUE_GPIO_BASE, LED_BLUE_PIN, 1U);
}
//Pins module initialization button
void PINS_Btn_Init(){
//Enable PMC clock
CLOCK_SYS_ConfigModuleClock(PMC_CLK, NULL);
//Set pin mode
PINS_SetMuxModeSel(KEY1_PORT_BASE, KEY1_PIN, PM_MUX_AS_GPIO);
PINS_SetMuxModeSel(KEY2_PORT_BASE, KEY2_PIN, PM_MUX_AS_GPIO);
//Set pin interrupt
PINS_SetPinIntSel(KEY1_PORT_BASE, KEY1_PIN, PM_INT_RISING_EDGE);
PINS_SetPinIntSel(KEY2_PORT_BASE, KEY2_PIN, PM_INT_RISING_EDGE);
//Set input direction
PINS_SetPinDir(KEY1_GPIO_BASE, KEY1_PIN, 0);
PINS_SetPinDir(KEY2_GPIO_BASE, KEY2_PIN, 0);
PINS_ClrPinInt**Cmd(KEY1_PORT_BASE, KEY1_PIN);
PINS_ClrPinInt**Cmd(KEY2_PORT_BASE, KEY2_PIN);
}
//Main function
int main(void){
//Initialize clock
CLOCK_SYS_Init(&g_clockConfig);
//Led init
LED_Init();
PINS_WritePin(LED_GPIO, BLUE_LED_PIN, 1);
PINS_WritePin(LED_GPIO, GREEN_LED_PIN, 1);
PINS_WritePin(LED_GPIO, RED_LED_PIN, 1);
//UART init
COM_Init();
//button init
PINS_Btn_Init();
//set PMC interrupt callback function
INT_SYS_InstallHandler(PMC_IRQn,&KEY_IRQHandler,(ISR_T*) 0);
INT_SYS_InstallHandler(SysTick_IRQn,&SysTick_Handler,(ISR_T*) 0);
//Enable PMC interrupt
INT_SYS_EnableIRQ(PMC_IRQn);
INT_SYS_EnableIRQ(SysTick_IRQn);
//ADC init
ADC_init();
SysTick_Init();
lcdInit();lcdClear();dispBase();
printf("Test G32A1465 lcdDisp adc keyInt and ...\r\n");
while (1){
  if(js>999999)js=0;//else js++;
//Calculated voltage value Output ADC conversion value
  adcValue = ADC_readValue()/g_adcMaxValue*g_adcDifference;
  printf("ADC conversion voltage value = %fV Key=%3d \r\n",adcValue,kk);
  dispMes();
  LED_On(2);SysTick_Delay_ms(1);LED_Off(2);
  SysTick_Delay_ms(100);
}
}
//end of group ADC_SoftwareConversion_Functions and group ADC_SoftwareConversion and group Examples
g32a1xxx_int.c中头部增加的:
extern uint32_t js;
void SysTick_Handler(void){
        js++;
    OSIF_Tick();
    TimingDelay_Decrement();
}
至此实验到此又完成了一个,自定义终端的方法。
照片1是串口输出的采集;照片2LCD显示js=的蹦字。只能看清千进位的增加,后边的太快看不清此时的技术是准确的,想显示的慢点只需要将显示的内容再除掉123位即可。
视频链接地址:

8_01.jpg (382.48 KB )

8_01.jpg

8_2.jpg (2.37 MB )

8_2.jpg

使用特权

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

本版积分规则

个人签名:永远好心情 [img]https://bbs.21ic.com/static/image/s

58

主题

265

帖子

1

粉丝