芯查查logo
  • 物料选型
  • 数据服务
    1. 新产品
    2. 查替代
    3. 丝印反查
    4. 查品牌
    5. PCN/PDN
    6. 查方案
    7. 查代理
    8. 数据合作
  • SaaS/方案
      SaaS产品
    1. 供应链波动监测预警
    2. 半导体产业链地图
    3. BOM管理
    4. 解决方案
    5. 汽车电子
    6. 政府机构
    7. 数据API
  • 商城
  • 行业资讯
    1. 资讯
    2. 直播
  • 论坛社区
    1. 论坛
    2. 学习
    3. 测评中心
    4. 活动中心
    5. 积分商城
  • 查一下
聪聪哥哥
极海APM32F035低压电机通用评估板-外设调试记录(二)

极海APM32F035低压电机通用评估板-基本外设调试记录(二)

上一篇我们将极海公司,利用keil的软件编译环境搭建简单的学习了一下,今天我们学习一下APM32F035的几个基本的外设。 

  1. 新建APM32F305代码的工程

参考官方的sdk包里面代码:

值得注意的是:官方提供的启动文件里面的内容,尽量不要修改,否则导致程序运行出错。

 

一:    简单调试使用

基本上所有的开发板上面第一个功能介绍是如何创建工程,第二个就是简单介绍IO口的操作,而最直接的就是利用LED灯作为显示,这样能清晰的看到IO口的高低电平。

 参考原理图:

整个电路板只有两个0603封装的LED灯,一个是用来指示电源电路是否正常,另外一个是故障指示灯(PC15),当IO口输出高电平时,指示灯熄灭,输出低电平时,指示灯亮起。

首先要初始化使用的IO口:

#define LEDn                             2

#define LED2_PIN                         GPIO_PIN_15

#define LED2_GPIO_PORT                   GPIOC

#define LED2_GPIO_CLK                    RCM_AHB_PERIPH_GPIOC

  void GPIO_Init(void)
{
   GPIO_Config_T gpioConfig;

   RCM_EnableAHBPeriphClock(LED2_GPIO_CLK | LED3_GPIO_CLK);
   /* LED2 GPIO configuration */
   gpioConfig.pin = LED2_PIN;
   gpioConfig.mode = GPIO_MODE_OUT;
   gpioConfig.outtype = GPIO_OUT_TYPE_PP;
   gpioConfig.speed = GPIO_SPEED_50MHz;
   gpioConfig.pupd = GPIO_PUPD_NO;
   GPIO_Config(LED2_GPIO_PORT, &gpioConfig);

   /* LED3 GPIO configuration */
   gpioConfig.pin = LED3_PIN;
   GPIO_Config(LED3_GPIO_PORT, &gpioConfig);
}          

 

注意要使能PCIO口的时钟,要不然io口是不会工作的。

  void APM_MINI_DelayMs(__IO uint32_t nms)
{
   uint32_t temp;

   SysTick->LOAD = (uint32_t)nms * cntMs;
   SysTick->VAL = 0x00;
   SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
   do
   {
       temp = SysTick->CTRL;
   }
   while ((temp & 0x01) && !(temp & (1 << 16)));
   SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
   SysTick->VAL = 0x00;
}

这里为了显示状态的改变时用了500ms的延时,当然本身这种延时函数是没有问题的,但是以后在工作中不要用类似的延时,很影响程序的运行。试验效果将在下面的视频中展示。

 

 

 

 

 

 

 

 

 

二:外部中断(EINT)简单调试使用

                                        
引脚输入信号引起的中断/事件,在中断向量表中指 EINTx;其它中断指内部中断
    
 事件可分为硬件事件、软件事件。硬件事件是通过外部/内核硬件信号产生事件,
软件事件是通过指令产生事件。
 中断需经过中断处理函数实现需要处理的工作;事件不需要经过中断处理函数,
可硬件触发预先设置的工作。外部事件例如可通过事件是 GPIO 输出脉冲,内部
事件例如通过一个 TMR 的更新事件触发另一个 TMR 工作。

这里我们用板载的按键K1(PC14)和LED灯(PC15)两个IO口调试这个功能。

中断初始化函数:

   void EINT_Init(void)
{
   GPIO_Config_T gpioConfig;
   EINT_Config_T eintConfig;

   /* Enable the BUTTON Clock */
   RCM_EnableAHBPeriphClock(KEY1_BUTTON_GPIO_CLK);
   RCM_EnableAHBPeriphClock(KEY2_BUTTON_GPIO_CLK);
//  RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
    
    
   RCM_EnableAPB2PeriphClock(RCM_AHB_PERIPH_GPIOC);    

   /* Condiv Button pin as input floating */
   gpioConfig.mode = GPIO_MODE_IN;
   gpioConfig.pupd = GPIO_PUPD_PU;
   gpioConfig.pin = KEY1_BUTTON_PIN;
   GPIO_Config(KEY1_BUTTON_GPIO_PORT, &gpioConfig);

   gpioConfig.pin = KEY2_BUTTON_PIN;
   GPIO_Config(KEY2_BUTTON_GPIO_PORT, &gpioConfig);

   /* Condiv GPIO pin used as EINT Line */
   SYSCFG_EINTLine(SYSCFG_PORT_GPIOC, SYSCFG_PIN_14);
   SYSCFG_EINTLine(SYSCFG_PORT_GPIOA, SYSCFG_PIN_0);

   /* Condiv Button exit line */
   eintConfig.line    =  KEY1_BUTTON_EXTI_LINE;
   eintConfig.lineCmd =  ENABLE;
   eintConfig.mode    =  EINT_MODE_INTERRUPT;
   eintConfig.trigger =  EINT_TRIGGER_FALLING;
   EINT_Config(&eintConfig);

   eintConfig.line    =  KEY2_BUTTON_EXTI_LINE;
   EINT_Config(&eintConfig);

   /* Condiv NVIC_IRQRequest */
   NVIC_EnableIRQRequest(EINT4_15_IRQn, 0x0F);
}              

 

这里需要将SDK包中的中断函数中的:EINT0_1_IRQn更改为EINT4_15_IRQn;IO口初始化时,将KEY1_BUTTON_GPIO_CLK的IO口定义更改为PC14,

但是我调试中断的时候发现,利用ST-LINK下载的时候,在仿真状态的时候,需要增加一个断点,程序才可以正常进入中断,但是我直接通电的时候,LED的指示灯是不正常工作的,我怀疑是中断函数根本就没有启作用。测试过上电延时200ms也没有解决。等有时间在弄这个bug吧。

 

     

 

原理图显示:

查询数据手册是串口2

主要代码如下:

int main(void)
{
    
        APM_MINI_DelayInit();
    
    
   GPIO_Config_T gpioConfig;
   USART_Config_T usartConfig;
   APM_MINI_COMInit(COM2);

   /* Enable GPIO clock */
   RCM_EnableAHBPeriphClock(MINI_COM1_TX_GPIO_CLK | MINI_COM2_TX_GPIO_CLK);

   /* Enable COM1 clock */
   RCM_EnableAPB2PeriphClock(MINI_COM2_CLK);

   /* Connect PXx to USARTx_Tx */
   GPIO_ConfigPinAF(MINI_COM2_TX_GPIO_PORT, MINI_COM2_TX_SOURCE, MINI_COM2_TX_AF);

   /* Connect PXx to USARRX_Rx */
   GPIO_ConfigPinAF(MINI_COM2_RX_GPIO_PORT, MINI_COM2_RX_SOURCE, MINI_COM2_RX_AF);

   /* Condiv USART Tx as alternate function push-pull */
   gpioConfig.mode = GPIO_MODE_AF;
   gpioConfig.pin = MINI_COM2_TX_PIN;
   gpioConfig.speed = GPIO_SPEED_50MHz;
   gpioConfig.outtype = GPIO_OUT_TYPE_PP;
   gpioConfig.pupd = GPIO_PUPD_PU;
   GPIO_Config(MINI_COM2_TX_GPIO_PORT, &gpioConfig);

   /* Condiv USART Rx as input floating */
   gpioConfig.pin  = MINI_COM2_RX_PIN;
   GPIO_Config(MINI_COM2_RX_GPIO_PORT, &gpioConfig);

   /* MINI_USARTs condivd as follow:  */
   /* BaudRate = 115200 baud   */
   usartConfig.baudRate = 115200;
   /* Receive and transmit enabled  */
   usartConfig.mode = USART_MODE_TX_RX;
   /* Hardware flow control disabled (RTS and CTS signals) */
   usartConfig.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
   /* No parity  */
   usartConfig.parity = USART_PARITY_NONE;
   /* One Stop Bit  */
   usartConfig.stopBits = USART_STOP_BIT_1;
   /* Word Length = 8 Bits  */
   usartConfig.wordLength = USART_WORD_LEN_8B;
   /* USART_Config  */
   USART_Config(MINI_COM2, &usartConfig);

   /* Enable USART_Interrupt_RXBNEIE*/
   USART_EnableInterrupt(MINI_COM2, USART_INT_RXBNEIE);

   NVIC_EnableIRQRequest(MINI_COM2_IRQn, 2);

   /* Enable USART */
   USART_Enable(MINI_COM2);

   /* MINI_COM1 Send data to PC, and you need to open serial assistant to observe*/
    USART_Write(MINI_COM2, (uint8_t*)"芯查查 APM32F035通用控制板串口调试r\n");

   while (1)
   {
            
        APM_MINI_DelayMs(500);
USART_Write(MINI_COM2, (uint8_t*)"芯查查 APM32F035通用控制板串口调试r\n");
}
 

 

利用ISP-STC软件 查看一下串口数据:

 

 

 

     3的PWM输出功能调试

APM32的定时器资源是比较丰富的,由于板子上面只有将PA7引脚引出,查看手册PA7引脚是可以复用定时器3的复用1功能;资料如下图所示:

  void APM_MINI_TMR1_PWMOutPut_Init(void)
{
   TMR_TimeBase_T  timeBaseConfig;
   TMR_OCConfig_T  occonfig;
   GPIO_Config_T   gpioconfig;

   /* Enable Clock*/
   RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
//    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
//    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);

   /* Connect TMR1 to CH1 */
//    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_8, GPIO_AF_PIN2);
//    gpioconfig.mode  = GPIO_MODE_AF;
//    gpioconfig.outtype = GPIO_OUT_TYPE_PP;
//    gpioconfig.pin   = GPIO_PIN_8;
//    gpioconfig.pupd  = GPIO_PUPD_NO;
//    gpioconfig.speed = GPIO_SPEED_50MHz;
//    GPIO_Config(GPIOA, &gpioconfig);
        RCM_EnableAPB1PeriphClock(RCM_APB2_PERIPH_SYSCFG);
   RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
    
   /* Connect TMR1 to CH1 */
   GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_PIN1);
   gpioconfig.mode  = GPIO_MODE_AF;
   gpioconfig.outtype = GPIO_OUT_TYPE_PP;
   gpioconfig.pin   = GPIO_PIN_7;
   gpioconfig.pupd  = GPIO_PUPD_NO;
   gpioconfig.speed = GPIO_SPEED_50MHz;
   GPIO_Config(GPIOA, &gpioconfig);    
    
    
    
   /* Set clockDivision = 1 */
   timeBaseConfig.clockDivision = TMR_CKD_DIV1;
   /* Up-counter */
   timeBaseConfig.counterMode = TMR_COUNTER_MODE_UP;
   /* Set divider = 47 .So TMR1 clock freq ~= 48/(47+1) = 1MHZ */
   timeBaseConfig.div = 47 ;
   /* Set counter = 1000 */
   timeBaseConfig.period = 500-1;
   /* Repetition counter = 0x0 */
   timeBaseConfig.repetitionCounter = 0;
   TMR_ConfigTimeBase(TMR3, &timeBaseConfig);

   /* PWM1 mode */
   occonfig.OC_Mode = TMR_OC_MODE_PWM2;
   /* Idle State is reset */
   occonfig.OC_Idlestate = TMR_OCIDLESTATE_RESET;
   /* NIdle State is reset */
   occonfig.OC_NIdlestate = TMR_OCNIDLESTATE_RESET;
   /* Enable CH1N ouput */
   occonfig.OC_OutputNState = TMR_OUTPUT_NSTATE_DISABLE;
   /* Enable CH1 ouput */
   occonfig.OC_OutputState = TMR_OUTPUT_STATE_ENABLE;
   /* CH1  polarity is high */
   occonfig.OC_Polarity = TMR_OC_POLARITY_HIGH;
   /* CH1N polarity is high */
   occonfig.OC_NPolarity = TMR_OC_NPOLARITY_HIGH;
   /* Set compare value */
   occonfig.Pulse = 250-1;
   TMR_OC2Config(TMR3, &occonfig);

   /* Enable PWM output */
   TMR_EnablePWMOutputs(TMR3);
   /* Enable TMR1  */
   TMR_Enable(TMR3);
}

 上述代码是在定时器1的代码进行修改的。需要修改引脚配置,定时器3的时钟和PWM的输出函数,当所有配置完成后,最后再使能定时器3,实际效果如下图:

输出脉冲计算公式:48MHZ/48 =1M;

1M/500 = 2000  = 2K;占空比修改              该项参数;

(偷偷问一句:用商城兑换的手持示波器会不会有BUFF加成)

 

 

具体定时时间很好计算,主频是120mhz,然后arr好prc是199和999,所以每次触发的时间就是1ms,之后是定时器的回调函数

ADC调试过程:

APM32内部ADC介绍:   位精度的   ,共   个通道,   个外部通道和  个内部通道,各通道   转换模式有单次、连续和断续,    转换结果可以左对齐或右对齐存储在   位数据寄存器中。

查看原理图,板载了一个10K的电位器,需要将PA7的引脚进行修改;代码如下:

  void ADC_Init(void)
{
   ADC_Config_T  adcConfig;
   GPIO_Config_T gpioConfig;
   /* RCM Enable*/
        /* RCM Enable*/
   RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
   RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC);
   RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
   /* GPIO Configuration */
   gpioConfig.pin = GPIO_PIN_7;
   gpioConfig.mode = GPIO_MODE_AN;
   gpioConfig.pupd = GPIO_PUPD_PU;
   GPIO_Config(GPIOA, &gpioConfig);
   /* ADC Configuration */
   ADC_Reset();
   ADC_ConfigStructInit(&adcConfig);
   /* Set resolution*/
   adcConfig.resolution    = ADC_RESOLUTION_12B;
   /* Set dataAlign*/
   adcConfig.dataAlign     = ADC_DATA_ALIGN_RIGHT;
   /* Set scanDir*/
   adcConfig.scanDir       = ADC_SCAN_DIR_UPWARD;
   /* Set convMode continous*/
   adcConfig.convMode      = ADC_CONVERSION_CONTINUOUS;
   /* Set extTrigConv*/
   adcConfig.extTrigConv1  = ADC_EXT_TRIG_CONV_TRG7;
   /* Set TrigEdge*/
   adcConfig.extTrigEdge1  = ADC_EXT_TRIG_EDGE_NONE;

   ADC_Config(&adcConfig);
   ADC_ConfigChannel(ADC_CHANNEL_7, ADC_SAMPLE_TIME_239_5);
   /* Enable Interrupt*/
   ADC_EnableInterrupt(ADC_INT_CS);

   NVIC_EnableIRQRequest(ADC_COMP_IRQn, 2);

   /* Enable VREFINT*/
   ADC_EnableVrefint();

   /* Calibration*/
   ADC_ReadCalibrationFactor();
   /* Enable ADC*/
   ADC_Enable();
}
void ADC_Isr(void)
{
   uint32_t adcData = 0;
   float voltage = 0.0;

   if (ADC_ReadIntFlag(ADC_INT_FLAG_CS) == SET)
   {
       ADC_ClearIntFlag(ADC_INT_FLAG_CS);
       /* Read ADC Conversion value */
       adcData = ADC_ReadConversionValue();

       voltage = ((float)adcData / 4095) * 3300;

       /* output to serial port */
       printf("Vref voltage : %.3f mV\r\n", voltage);

       APM_MINI_LEDToggle(LED2);
       APM_MINI_DelayMs(500);
   }
}

初始化ADC,并配置PA7为输入模式,更改中断号就可以正常调试;但是内部的ADC调试的时候会存在误差的,我在调试的时候发现,内部AD到不了满值,

一起学习
版块: 极海半导体
2024/03/21 17:20
  • 举报
😁😂😃😄😅😆😉😊😋😌😍😏😒😓😔😖😘😚😜😝😞😠😡😢😣😤😥😨😩😪😫😭😰😱😲😳😵😷😸😹😺😻😼😽😾😿🙀🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏✂✅✈✉✊✋✌✏✒✔✖✨✳✴❄❇❌❎❓❔❕❗❤➕➖➗➡➰🚀🚃🚄🚅🚇🚉🚌🚏🚑🚒🚓🚕🚗🚙🚚🚢🚤🚥🚧🚨🚩🚪🚫🚬🚭🚲🚶🚹🚺🚻🚼🚽🚾🛀Ⓜ🅰🅱🅾🅿🆎🆑🆒🆓🆔🆕
@好友

全部评论

加载中
游客登录通知
已选择 0 人
自定义圈子
移动
发布帖子
发布动态
发布问答
最新帖子
UC3843脉冲发生器zvs大功率零电压开关反激电源参数计算与器件选型,反激变压器计算与绕制教程【开源】基于UC3842芯片的24V3A反激式开关电源【星允派 NEBULA PI】18:使用PWM驱动RGB灯
热门版块
查看更多
问型号
问技术
问行情
汽车电子工程师论坛
工业电子专区
新手入门指南
专家问答
单片机/MCU论坛
PCB设计
开源项目

121

收藏

分享

微信扫码
分享给好友

评论