13、RH850 F1 选项字节和看门狗

本文详细介绍了RH850微控制器的选项字配置,特别是OPBT0和OPBT1寄存器的用途,以及看门狗定时器(WDTA)的设置和操作,包括中断请求、复位源和模式选择。同时,提供了初始化看门狗的示例代码。

前言:

       选项字OPTION配置是RH850的一项重点,用户手册对选项字的配置介绍很少,这篇文章将主要针对选项字和看门狗的配置进行讲解。

一、选项字特性

       闪存的选项字节是一个扩展区域,并保存用户为各种目的指定的数据。由选项字节指定的外围模块等的初始设置在从复位状态释放时生效。

二、选项字设置

       在将程序写入闪存之前,请确保设置对应于下面列出的可选函数的选项字节区域。

三、选项字寄存器

3.1  OPBT0 — Option Byte 0

Bit position

Bit Name

Function

30 - 29

OPJTAG

这些位控制端口组JP0的功能。

00: JP0用于通用/替代功能端口

01: JP0用于LPD 4引脚模式

10: JP0用于LPD 1引脚模式

11: JP0用于Nexus I/F

26

WDT1_3

指定WDTA1的激活码方法。

0:固定激活码

1:变量激活码

24

WDT1_1

指定WDTA1的启动方式。

0:软件触发启动

1:默认启动

23

WDT1_0

启用或禁用WDTA1。

0:关闭WDTA1

1:启用WDTA1

22

WDT0_3

指定WDTA0的激活码方法。

0:固定激活码

1:变量激活码

20

WDT0_1

指定WDTA0的启动方式。

0:软件触发启动

1:默认启动

19

WDT0_0

启用或禁用WDTA0。

0:关闭WDTA0

1:使能WDTA0

18 - 16

WDT_2-0

控制WDTA0和WDTA1的溢出间隔时间

这些位指定WDTAnMD.WDTAnOVF[2:0]的重置值。

10

CANFDCRC

CAN FD CRC协议

0:原协议

1:新协议

9

RESET OUTEN

复位控制

0:禁止复位功能

1:允许复位功能

5

CVM_H D_EN

压监控使能

0:关闭高压检测

1:开启高压检测

4

CVM_L D_EN

压监控使能

0:关闭低压检测

1:开启低电压检测

3.2  OPBT1 — Option Byte 1

Bit position

Bit Name

Function

31 - 10

写时,写“1”。

9

写时,写“0”。

8 - 0

写时,写“1”。

四、功能概述

(1)编程或擦除中断的读取区域

       当对闪存区域的编程或擦除被中断时,存储在该区域中的数据将变为未定义。为了避免读取未定义的数据,这可能会导致故障,请注意不要从编程或擦除中断的区域获取指令或读取数据

(2)读取已擦除但尚未编程的代码闪存

       请注意,从已擦除但尚未再次编程的代码闪存中读取(即处于非编程状态)可能会导致检测到ECC错误并产生相应的异常。当需要确认某个区域处于非编程状态时,使用空白检查。

(3)禁止增写

       向一个给定区域写入两次或两次以上是不可能的。当对闪存区域完成写入后覆盖该区域中的数据时,请先擦除该区域。

(4)在编程和擦除过程中重置

       在编程和擦除过程中发生外部复位的情况下,在断言复位信号后,一旦工作电压在电气特性规定的范围内,至少等待复位输入低电平宽度的最小值,然后将设备从复位状态释放。

(5)在编程和擦除过程中为中断和其他异常分配向量

       在编程或擦除过程中产生中断或其他异常可能导致从代码闪存中获取向量。如果这不满足使用后台操作的条件,将vector获取的地址设置为不在代码闪存中的地址。

(6)编程异常终止和擦除

       即使由于reset引脚的复位断言而导致编程/擦除异常结束,具有未定义数据的闪存的编程/擦除状态也不能被验证或检查。对于编程/擦除异常结束的区域,空白检查功能无法判断该区域是否擦除成功。再次擦除该区域,以确保相应的区域使用前完全擦除。

       如果编程和擦除代码闪存没有正常完成,目标区域的锁定位可能被启用(锁定)。在这种情况下,请在锁定位处于禁用状态(该区域未锁定)时擦除该块以清除锁定位。

(7)编程和擦除过程中禁止的项目

       请勿在编程和擦除过程中执行以下操作。

•将电源的工作电压设置在允许的范围之外。

•修改外部时钟频率。

(8)清除配置前擦除所有闪存

       在清除配置之前,请擦除代码flash的用户区域和数据flash的所有数据区域。

(9)使用HS IntOSC时串行编程的限制

       不能使用1线/2线UART模式。

       无法使用E1仿真器。

五、RH850_F1K选项字配置

六、WDTA - 窗口看门狗

       本节包含窗口看门狗定时器(WDTA)的一般描述。

       本节的第一部分描述了RH850/F1K的所有特定属性,例如单元数、寄存器基址等。本节的其余部分将描述WDTA的函数和寄存器。

6.1 单位和通道数量

这个微控制器有以下数量的WDTA单元。

6.2 寄存器基地址

基地址名称

基地址

WDTA0_base

FFED 0000

WDTA1_base

FFED 1000

6.3 时钟源选择

名称

时钟源名称

时钟源选择名称

介绍

WDTA0

WDTATCKI

CKSCLK_AWDTA

定时器计数时钟

注册访问时钟

CPUCLK2

总线时钟

WDTA1

WDTATCKI

LS IntOSC

定时器计数时钟

注册访问时钟

CPUCLK2

总线时钟

6.4 中断请求

下表列出了WDTAn中断请求。

6.5 复位源

下表列出了WDTAn复位源。WDTAn由这些重置源初始化。

名称

复位源

WDTA0

复位源AWORES

WDTA1

所有复位源ISORES

6.6 看门狗框图

6.7 寄存器

6.71 WDTAnWDTE -- 看门狗使能寄存器

Bit position

Bit Name

Function

7 - 0

WDTAnRUN

编写固定激活代码(ACH)生成WDTA触发器并启动/ 重新启动WDTAn计数器。写入ACH以外的值会产生错误。

WDTAn一旦启动就不能停止。

6.72 WDTAnEVAC -- 看门狗使能VAC寄存器

Bit position

Bit Name

Function

7 - 0

WDTAnEVAC

编写变量激活代码生成WDTA触发器并启动/重新启动WDTA计数器。编写不正确的激活代码将生成错误。WDTAn一旦启动就不能停止。

6.73 WDTAnREF -- 参考值寄存器

Bit position

Bit Name

Function

7 - 0

WDTAnREF

VAC功能的激活码计算参考值

6.74 WDTAnMD -- 看门狗模式寄存器

Bit position

Bit Name

Function

6 - 4

WDTAnOVF

选择溢出间隔时间

WDTAnOVF2

WDTAnOVF1

WDTAnOVF0

溢出间隔时间

0

0

0

2^9/WDTATCKI

0

0

1

2^10/WDTATCKI

0

1

0

2^11/WDTATCKI

0

1

1

2^12/WDTATCKI

1

0

0

2^13/WDTATCKI

1

0

1

2^14/WDTATCKI

1

1

0

2^15/WDTATCKI

1

1

1

2^16/WDTATCKI

3

WDTAnWIE

启用/禁用75%中断请求INTWDTAn。

0:关闭INTWDTAn功能。

1:使能INTWDTAn。

2

WDTAnERM

指定错误模式。

0: NMI请求模式

1:复位模式

1 - 0

WDTAnWS

选择窗口打开周期。

WDTAnWS1

WDTAnWS0

窗口打开周期

0

0

25%

0

1

50%

1

0

75%

1

1

100%

七、看门狗例程

/**********************************************************************

 * Description: Initializes and starts the Watch Dog for reset generation

 * Parameters : None

 * Returns : None

*********************************************************************/

void Init_WatchDog(void)

{

    uint32_t  reg32_value;

    // Set interrupt flags

    INTC2MKWDTA0                       = 1U;

    INTC2RFWDTA0                       = 0U;

    INTC2TBWDTA0                       = 1U;

    do

    {

        reg32_value               = 0x00000001UL;

        WPROTRPROTCMD0                  = 0x000000A5UL;     // Protection release the CKSC_AWDTAD_CTL register.

        CLKCTLCKSC_AWDTAD_CTL           = reg32_value;

        CLKCTLCKSC_AWDTAD_CTL           = ~reg32_value;

        CLKCTLCKSC_AWDTAD_CTL           = reg32_value;

    } while ( PORTPPROTS0 != 0x00000000UL );

    while ( CLKCTLCKSC_AWDTAD_ACT != reg32_value )

    {

        // Waiting for CKSC_AWDTAD_CTL to set.

    }

    WDTA0MD                      = 0x0FU;

    INTC2MKWDTA0                       = 0U;        // INTWDTA0 (75% interrupt) enable

    WDTA0WDTE = 0xAC;

    Feed_Dog();                         // feed both dogs to initialize

}

/**********************************************************************

 * Description: Watchdog timer interval (75% of overflow time)

 * Parameters : None

 * Returns : None

 *********************************************************************/

#pragma vector = INTWDTA0_vector

__interrupt void vWatchDogTimerINT(void)

{

    /* make sure feed dog in 75% of overflow time,

      so watchdog_count can identify the count of reset occur by watchdog overflow time  */

static int watchdog_count;

INTC2RFWDTA0 = 0U; /* clear INTWDTI interrupt flag */

watchdog_count++;

}

/** ****************************************************************************** * @file PWR_STOP/main.c * @author MCD Application Team * @version V1.0.1 * @date 11-October-2013 * @brief Main program body ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> * * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "MM32F031xxn.h" #include <math.h> //Library #include "user.h" #include "control_circuit.h" //函数声明 void on_off(uint8_t num); void uart2_report(void); void uart1_communication(void); void report2_format(void); void auto2_sending(void); void Delay_Ms(uint32_t time_ms); //变量声明 uint32_t counter_cycle, uart1_rate, uart2_rate, cntr_unse, cntr_tim14; uint16_t adc_v, voltage, o2c, o2f, o2t, o2RH, o2P; uint32_t o2p, kpa; uint8_t USART1_TXbuffer[30], USART1_RXbuffer[30], USART2_TXbuffer[30], USART2_RXbuffer[30], buf_us6300[4], report8[30]; u8 flag_pad, flag_menu, flag_light, battery, display_flag; uint16_t voltage_buffer[15], power_off_cntr; uint8_t rx_flag, code_right, code_num, flag_adj, flash_write; uint8_t USART1_RXtotal, USART1_TXtotal, USART2_RXtotal, USART2_TXtotal, flag_preparing_report, sensor_num; float o2c_factor, o2f_factor, atm, temperature; uint8_t I2C1_Tx_Buffer[16]; uint8_t I2C1_Rx_Buffer[16]; //void data_init(void) //{ // STMFLASH_Read (FLASH_STORE_BASE_ADDR,(uint8_t*)I2C1_Rx_Buffer,16); // if((I2C1_Rx_Buffer[0]==0xAA)&&(I2C1_Rx_Buffer[3]==0x55)) // { // o2c_add = I2C1_Rx_Buffer[1]; // o2f_add = I2C1_Rx_Buffer[2]; // } // else // { // I2C1_Tx_Buffer[0] = 0xAA; // I2C1_Tx_Buffer[1] = o2c_add; // I2C1_Tx_Buffer[2] = o2f_add; // I2C1_Tx_Buffer[3] = 0x55; // STMFLASH_Write(FLASH_STORE_BASE_ADDR,(uint8_t*)I2C1_Tx_Buffer,16); // } // if(o2f_add>0x80) // o2f_factor = 1 + 0.01*(o2f_add - 0x80); // else // o2f_factor = 1 - 0.01*(0x80-o2f_add); //} int main(void) { GPIO_InitTypeDef GPIO_InitStructure; uint32_t i; uint8_t enable; for (i=0;i<MILLISECOND*64*10;i++){} // 这段延时不可省去: // ------初始化全局变量------------ o2c = 210; o2f = 0; sensor_num = 0; flag_menu = 0; flash_write = 0; stm32_Init (); uart1_communication(); uart2_report(); ControlCircuit_Init(); // 初始化12V控制IO // data_init(); LED_ON; for (i=0;i<MILLISECOND*64*10;i++){} // 这段延时不可省去: LED_OFF; VAL_ON; // 开启12V输出 Voltage12V_Control(1); // 关闭12V输出 //Voltage12V_Control(0); // I2CInitMasterMode(); // I2CMasterWrite(I2C1,US6300_ADDR, 0x06, 0, buf_us6300); for (i=0;i<500000;i++){}; // 这段延时可导致标定时通信不正常;但有时,在线仿真时没有此延时,EEPROM无法通过; // I2CMasterWrite(I2C1,US6300_ADDR, 0x50, 0, buf_us6300); // for (i=0;i<500;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0x30, 0, buf_us6300); // for (i=0;i<500;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0xAA, 0, buf_us6300); // for (i=0;i<500000;i++){} // 这段延时可导致标定时通信不正常;但有时,在线仿真时没有此延时,EEPROM无法通过; // IWDG->KR = 0xAAAA; // 刷新看门狗IWDG ;写入0xAAAA=装入重载值; IWDG->KR = 0xCCCC; // 启动看门狗; IWDG->KR = 0xAAAA; // 刷新看门狗IWDG; 写入0xAAAA=装入重载值; // I2CMasterWrite(I2C1,US6300_ADDR, 0xAA, 0, buf_us6300);//读第一次数据时必须唤醒3次 // for (i=0;i<500000;i++){} // 这段延时可导致标定时通信不正常;但有时,在线仿真时没有此延时,EEPROM无法通过; // IWDG->KR = 0xAAAA; // 刷新看门狗IWDG ;写入0xAAAA=装入重载值; // ***************************************************** while(1) { IWDG->KR = 0xAAAA; // 刷新看门狗IWDG ;写入0xAAAA=装入重载值? if(flag_menu) { // I2CMasterWrite(I2C1,US6300_ADDR, 0x50, 0, buf_us6300); // for (i=0;i<5000;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0x50, 0, buf_us6300); // for (i=0;i<5000;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0x30, 0, buf_us6300); // for (i=0;i<5000;i++){}; // I2CMasterRead1_6300(I2C1,US6300_ADDR, 3, buf_us6300); // atm = ((buf_us6300[0]&0x0f)*256*256 + buf_us6300[1]*256 + buf_us6300[2])/1000.0; //value/10=hpa,kpa/6.895=psi,hpa/6.895=psi*10; // for (i=0;i<5000;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0x32, 0, buf_us6300); //温度 // for (i=0;i<5000;i++){}; // I2CMasterRead1_6300(I2C1,US6300_ADDR, 3, buf_us6300); // temperature = ((buf_us6300[0]&0x0f)*256*256 + buf_us6300[1]*256 + buf_us6300[2])/100.0; flag_menu = 0; } } } // ***************************************************************************************** // 准备常规报 // ***************************************************************************************** void report2_format(void) { uint32_t i,j; uint8_t temp, temp_AAA[4], temp2_AAA[20]; uint16_t temp_u16; uint32_t temp_u32; union AAA { float f[5] ; u8 u8_[20]; } convert; // convert.f[0] = (float)o2c/10; convert.f[1] = (float)o2RH/10; convert.f[2] = (float)o2t/10; //--传感器显示此数据 convert.f[3] = (float)o2P/10; convert.f[4] = (float)atm; for (i=0;i<5;i++) //5个浮点 { for (j=0;j<4;j++) temp_AAA[3-j] = convert.u8_[i*4+j]; for (j=0;j<4;j++) temp2_AAA[i*4+j] = temp_AAA[j]; } flag_preparing_report=1; //防止在变更过程中发送 for (i=0;i<20;i++) report8[i+4] = temp2_AAA[i]; //利用union将浮点转到report8中; report8[0]=0x16; report8[1]=0x09; report8[2]=0x01; report8[3]=sensor_num-1; temp = 0; for(i=0;i<24;i++) temp += report8[i]; report8[24] = 0x00 - temp; //计算校验字; for (i=0;i<25;i++) USART2_TXbuffer[i] = report8[i]; //将report8拷贝; report8[i] flag_preparing_report = 0; } // ******************************************************************************* // auto_sending自动发送浓度 // ******************************************************************************* void auto2_sending(void) //正常检测时,自动发送检测数据----复核时模式应该还是calibration, 符合完成后才改成NORMAL; { if(flag_preparing_report==0) //防护措施:防止数据准备未完成时发送; { DMA_Cmd(DMA1_Channel4, DISABLE); DMA1_Channel4->CMAR = (u32)&USART2_TXbuffer; DMA1_Channel4->CNDTR = USART2_TXtotal; //DMA通道的DMA缓存的大小 DMA_Cmd(DMA1_Channel4, ENABLE); } } void uart1_communication(void) { uint16_t temp_16; //GPIO端口设置 DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; UART_InitTypeDef UART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE); //使能UART2 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //开启GPIOA时钟 //UART1 NVIC 配置 //UART 初始化设置 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1); uart1_rate = 9600; UART_InitStructure.UART_BaudRate = uart1_rate;//串口波特率 USART1_TXtotal = 4; USART1_RXtotal = 12; UART_InitStructure.UART_WordLength = UART_WordLength_8b;//字长为8位数据格式 UART_InitStructure.UART_StopBits = UART_StopBits_1;//一个停止位 UART_InitStructure.UART_Parity = UART_Parity_No;//无奇偶校验位 UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;//无硬件数据流控制 UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; //收发模式 UART_Init(UART1, &UART_InitStructure); //初始化串口1 UART_Cmd(UART1, ENABLE); //使能串口1 //UART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //UART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 // printf("UART OK!\r\n"); //----------UART1_DMA配置部分------------------- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA1_Channel2); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(UART1->TDR); //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_TXbuffer; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = USART1_TXtotal; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel2, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道UART1_Tx_DMA_Channel所标识的寄存器 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) &(UART1->RDR); //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_RXbuffer; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,赐馍栌读取发送到内存 DMA_InitStructure.DMA_BufferSize = USART1_RXtotal; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel3, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道UART1_Tx_DMA_Channel所标识的寄存器 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE); // UART_DMACmd(UART1,UART_DMAReq_EN,ENABLE); //使能uart1 DMA DMA_ITConfig(DMA1_Channel3,DMA_IT_TC,ENABLE); UART_DMACmd(UART1,UART_DMAReq_EN,ENABLE); //使能uart1 DMA // DMA_Cmd(DMA1_Channel4, ENABLE); DMA_Cmd(DMA1_Channel3, ENABLE); } void uart2_report(void) { uint16_t temp_16; //GPIO端口设置 DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; UART_InitTypeDef UART_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART2, ENABLE); //使能UART2 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //开启GPIOA时钟 //UART1 NVIC 配置 //UART 初始化设置 GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1); uart2_rate = 115200; UART_InitStructure.UART_BaudRate = uart2_rate;//串口波特率 USART2_TXtotal = 25; USART2_RXtotal = 8; UART_InitStructure.UART_WordLength = UART_WordLength_8b;//字长为8位数据格式 UART_InitStructure.UART_StopBits = UART_StopBits_1;//一个停止位 UART_InitStructure.UART_Parity = UART_Parity_No;//无奇偶校验位 UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;//无硬件数据流控制 UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; //收发模式 UART_Init(UART2, &UART_InitStructure); //初始化串口1 UART_Cmd(UART2, ENABLE); //使能串口1 //UART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //UART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 // printf("UART OK!\r\n"); //----------UART1_DMA配置部分------------------- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //使能DMA传输 DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(UART2->TDR); //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_TXbuffer; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = USART2_TXtotal; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel4, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道UART1_Tx_DMA_Channel所标识的寄存器 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) &(UART2->RDR); //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_RXbuffer; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,赐馍栌读取发送到内存 DMA_InitStructure.DMA_BufferSize = USART2_RXtotal; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel5, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道UART1_Tx_DMA_Channel所标识的寄存器 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); // UART_DMACmd(UART1,UART_DMAReq_EN,ENABLE); //使能uart1 DMA DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE); UART_DMACmd(UART2,UART_DMAReq_EN,ENABLE); //使能uart1 DMA // DMA_Cmd(DMA1_Channel4, ENABLE); DMA_Cmd(DMA1_Channel5, ENABLE); } //** //矩阵切换 //** void on_off(uint8_t num) { uint8_t board, sensor_num; board = num%128/16; sensor_num = num%16; switch(board) //切换板编号 { case 0: EN0_ON; EN1_OFF; EN2_OFF; EN3_OFF; break; case 1: EN0_OFF; EN1_ON; EN2_OFF; EN3_OFF; break; case 2: EN0_OFF; EN1_OFF; EN2_ON; EN3_OFF; break; case 3: EN0_OFF; EN1_OFF; EN2_OFF; EN3_ON; break; } switch(sensor_num) //传感器编号 { case 15: A0_ON; A1_ON; A2_ON; A3_ON; break; case 14: A0_OFF; A1_ON; A2_ON; A3_ON; break; case 13: A0_ON; A1_OFF; A2_ON; A3_ON; break; case 12: A0_OFF; A1_OFF; A2_ON; A3_ON; break; case 11: A0_ON; A1_ON; A2_OFF; A3_ON; break; case 10: A0_OFF; A1_ON; A2_OFF; A3_ON; break; case 9: A0_ON; A1_OFF; A2_OFF; A3_ON; break; case 8: A0_OFF; A1_OFF; A2_OFF; A3_ON; break; case 7: A0_ON; A1_ON; A2_ON; A3_OFF; break; case 6: A0_OFF; A1_ON; A2_ON; A3_OFF; break; case 5: A0_ON; A1_OFF; A2_ON; A3_OFF; break; case 4: A0_OFF; A1_OFF; A2_ON; A3_OFF; break; case 3: A0_ON; A1_ON; A2_OFF; A3_OFF; break; case 2: A0_OFF; A1_ON; A2_OFF; A3_OFF; break; case 1: A0_ON; A1_OFF; A2_OFF; A3_OFF; break; case 0: A0_OFF; A1_OFF; A2_OFF; A3_OFF; break; } } //电压采样 void Get_Adc_Average(void) { uint8_t i; uint16_t temp_v, Temp_average_float; } //正常显示 void display(void) { } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ #include "user.h" //------全局变量定义------- //------全局变量定义------- void I2C_Configuration(void); //void ADC_CH_DMA_Config(void); /*配置DMA4_5的中断*/ void NVIC_Config() { NVIC_InitTypeDef NVIC_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_5_IRQn;//DMA1_Channel4_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_Init(&NVIC_InitStructure); } /*配置DMA4_5的中断*/ void Delay(uint32_t nCount) { while (nCount != 0) { nCount--; } } void uart_putc(unsigned char c) { while(!((UART1->ISR)&(1<<7))); UART1->TDR=c; } void uart_puts(char *s ) { while (*s) uart_putc(*s++); } void GPIO_INIT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_11|GPIO_Pin_12; //PA6-背光脚、PA7-STB、PA12-喇叭控制 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_5; //PB0-CLK、PB1-DIO、PB5-LED GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); PVCC_ON; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; //PB4-P_CS GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } /** * @brief Configures system clock after wake-up from STOP: enable HSE, PLL * and select PLL as system clock source. * @param None * @retval None */ void SYSCLKConfig_STOP(void) { /* After wake-up from STOP reconfigure the system clock */ /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till HSE is ready */ while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) {} /* Enable PLL */ RCC_PLLCmd(ENABLE); /* Wait till PLL is ready */ while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {} /* Select PLL as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Wait till PLL is used as system clock source */ while (RCC_GetSYSCLKSource() != 0x08) {} } //------------------------------------------------ //-----------------定时器配置--------------------- void stm32_TimerSetup (void) { //注意:TIMx中断不可轻易使能,因为如果TIMx已经启动,会自动引发中断,造成CPU无法跳到下一个断点;其中的原因还不甚明了; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE ); //开启tim14时钟 TIM16->CR1 = 0; // reset command register 1 TIM16->PSC = 1000; // set prescaler;TIM3_CLK=72MHz/1=72MHz TIM16->ARR = 500*FCLK_H_MHZ-1; // 100uS TIM16->DIER |=1<<0; // enable interrupt NVIC_InitStructure.NVIC_IRQChannel = TIM16_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority =0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM16->CR1 |= 1<<0; // 启动timer2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM14, ENABLE ); //开启tim17时钟 ---25ms TIM14->CR1 = 0; // reset command register 1 TIM14->PSC = 1000; // set prescaler;TIM3_CLK=72MHz/1=72MHz TIM14->ARR = 7*FCLK_H_MHZ-1; // 100uS TIM14->DIER |=1<<0; // enable interrupt NVIC_InitStructure.NVIC_IRQChannel = TIM14_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority =0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM14->CR1 |= 1<<0; // 启动timer2 } ///*---------------------------------------------------------------------------- // set HSI as SystemCoreClock (HSE is not populated on STM32L-Discovery board) // *----------------------------------------------------------------------------*/ void SystemCoreClockSetHSE(void) { RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Enable HSE */ while ((RCC->CR & RCC_CR_HSERDY) == 0); /* Wait for HSE Ready */ RCC->CFGR = RCC_CFGR_SW_HSE; /* HSE is system clock */ while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSE); /* Wait for HSE used as system clock */ // FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // FLASH_SetLatency(FLASH_Latency_1); FLASH->ACR = FLASH_ACR_PRFTBE; /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_Latency_2; /* Flash 1 wait state */ RCC->CFGR |= RCC_CFGR_HPRE_DIV1; /* HCLK = SYSCLK */ RCC->CFGR |= RCC_CFGR_PPRE1_DIV1; /* PCLK = HCLK */ RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; /* PCLK = HCLK */ RCC->CR &= ~RCC_CR_PLLON; /* Disable PLL */ /*PLL configuration: = HSE * 3 = 24 MHz */ // RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL); RCC->CFGR |=1<<16; RCC->CFGR &=~(1<<17); RCC->CR &=~(0x3f<<26); RCC->CR |=5 << 26; //设置PLL值 2~16 // RCC->CFGR |= (RCC_CFGR_PLLSRC_1 | RCC_CFGR_PLLMULL3); RCC->CR |= RCC_CR_PLLON; /* Enable PLL */ while((RCC->CR & RCC_CR_PLLRDY) == 0) __NOP(); /* Wait till PLL is ready */ RCC->CFGR &= ~RCC_CFGR_SW; /* Select PLL as system clock source */ RCC->CFGR |= RCC_CFGR_SW_PLL; while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); /* Wait till PLL is system clock src */ // RCC->CR &= ~RCC_CR_HSION; /* Disable HSI /必须配置完成才能关闭内部时钟*/ } //---------------------------------------------------------------------------- // STM32 Independent watchdog setup. // initializes the IWDG register //---------------------------------------------------------------------------- void stm32_IwdgSetup (void) { RCC->CSR|= (1<<0); // LSI enable, necessary for IWDG while ((RCC->CSR& (1<<1)) == 0); // wait till LSI is ready IWDG->KR = 0x5555; //写入0x5555表示允许访问IWDG->PR, IWDG->RLR while ((IWDG->SR& (1<<0)) == 1); IWDG->PR = 4; //预分频系数:0=/4;1=/8;2=/16;3=/32;4=/64;5=/128;6=/256;7=/256 while ((IWDG->SR& (1<<1)) == 1); IWDG->RLR = 0xFFF; // 重载值(0-4095)=(超时周期*时钟频率-1)=; // 重载值= 3秒*128-1=383 IWDG->KR = 0xAAAA; // 写入0xAAAA=装入重载值; //IWDG->KR.all = 0xCCCC; // 启动看门狗; } // end of stm32_IwdgSetup /** * @brief ADC1 channel with DMA configuration * @param None * @retval None */ void ADC_CH_DMA_Config(void) { ADC_InitTypeDef ADC_InitStruct; DMA_InitTypeDef DMA_InitStruct; GPIO_InitTypeDef GPIO_InitStruct; /* ADC1 DeInit */ ADC_DeInit(ADC1);//主要功能:先使能ADC1时钟,再失能ADC1时钟 /* Enable GPIOA clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* Configure PA.01 as analog input */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; //模拟输入浮空输入 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // PC1,输入时不用设置速率 /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE); /* DMA1 Channel1 Config */ DMA_DeInit(DMA1_Channel1); // DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;//stm32f030用 DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)&(ADC1->ADDATA); DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&adc_v; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStruct.DMA_BufferSize =1; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;// /* ADC DMA request in circular mode */ DMA_InitStruct.DMA_Priority = DMA_Priority_High; DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStruct); /* DMA1 Channel1 enable */ DMA_Cmd(DMA1_Channel1, ENABLE); /* Enable ADC_DMA */ ADC_DMACmd(ADC1, ENABLE); /* Initialize ADC structure */ ADC_StructInit(&ADC_InitStruct); /* ADC1 Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits */ ADC_InitStruct.ADC_PRESCARE = ADC_PCLK2_PRESCARE_2; ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; ADC_InitStruct.ADC_Mode = ADC_Mode_Continuous_Scan; // ADC_InitStruct.ADC_TRGEN = ADC_TRG_Disable;//不使用外部触发信号启动转换 ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_Init(ADC1, &ADC_InitStruct); /*屏蔽所有通道*/ ADC1->ADCHS&=0xffffffe00; /*使能选中通道,后面参数保留*/ ADC_RegularChannelConfig(ADC1, ADC_Channel_1 ,0 , ADC_SampleTime_13_5Cycles); // ADC_VrefintCmd(ENABLE); // ADC1->ADCFG|=0x04; 手册说该位保留,必须为0; ADC_ExternalTrigConvCmd(ADC1,DISABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); /* Wait the ADCEN falg */ // while(!ADC_GetFlagStatus(ADC1, RESET)); /* ADC1 regular Software Start Conv */ ADC_SoftwareStartConvCmd(ADC1,ENABLE); } //------------------------------------------------------------------ // STM32 embedded Flash interface setup. // initializes the ACR register //------------------------------------------------------------------ void stm32_EfiSetup (void) { // u32 temp; FLASH->ACR = 0x00000012; // set access control register;__EFI_ACR_Val=0x00000012 FLASH->ACR|= 2<<0; //0=SYSCLK<24Mhz,1=<24<SYSCLK<48Mhz,2=48<SYSCLK<72Mhz; // temp= FLASH->ACR.all; } //external interrupt initialprocedure void EXTIX_Init(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);//外部中断,需要使能AFIO时钟 // SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource3); // // EXTI_InitStructure.EXTI_Line=EXTI_Line3; // EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发 // EXTI_InitStructure.EXTI_LineCmd = ENABLE; // EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource11); EXTI_InitStructure.EXTI_Line=EXTI_Line11; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource15); EXTI_InitStructure.EXTI_Line=EXTI_Line15; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn; //使能按键所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPriority = 0x02; //子优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 // NVIC_InitStructure.NVIC_IRQChannel = EXTI2_3_IRQn; //使能按键所在的外部中断通道 // NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01; //子优先级1 // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 // NVIC_Init(&NVIC_InitStructure); } void stm32_Init () { // stm32_EfiSetup(); //已经在MM32F031系统时钟配置中配置过 SystemCoreClockSetHSE(); //SYSTICK_INIT(); //SYSTICK一定要谨慎使用,用不好会DEBUG冲突,貌似没什么用,不屏蔽又会报错 GPIO_INIT(); // USART_INIT(); // stm32_dmaSetup(); stm32_TimerSetup(); //RTC_Config(); //I2C_Configuration(); stm32_IwdgSetup(); // ADC_CH_DMA_Config(); // EXTIX_Init(); } /** ****************************************************************************** * @file PWR_STOP/stm32f0xx_it.c * @author MCD Application Team * @version V1.0.1 * @date 11-October-2013 * @brief Main Interrupt Service Routines. * This file provides template for all exceptions handler and * peripherals interrupt service routine. ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> * * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "MM32F031xxn.h" #include "user.h" #include "main.h" //************STM32F1函数以及变量定义******************************************* //****************************************************************************** /** * @brief This function handles NMI exception. * @param None * @retval None */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. * @param None * @retval None */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } } /** * @brief This function handles SVCall exception. * @param None * @retval None */ void SVC_Handler(void) { } /** * @brief This function handles PendSVC exception. * @param None * @retval None */ void PendSV_Handler(void) { } /** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { // STM_EVAL_LEDToggle(LED3); // TimingDelay--; } //void TIM17_IRQHandler(void) //{ // // TIM17->SR&= ~(1<<0); //清除中断标志;UIF // if(Flag_rx_dma==1) // { // Dma_clear_delay++; // } // if(Dma_clear_delay==7) //RX接收到数据后35ms开始更新dma防止干扰下次接收 // { // DMA_Cmd(DMA1_Channel5, DISABLE); /* Disable DMA1 Channel4 transfer */ // DMA1_Channel5->CNDTR=USART1_RXtotal; // DMA_Cmd(DMA1_Channel5, ENABLE); /* Enable DMA1 Channel4 transfer */ // //DMA1->IFCR|=1<<16; //清除DMA通道4的全部中断标志位; // Dma_clear_delay=0; // Flag_rx_dma=0; // } //} /******************************************************************************/ /* STM32F0xx Peripherals Interrupt Handlers */ /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ /* available peripheral interrupt handler's name please refer to the startup */ /* file (startup_stm32f0x8.s). */ /******************************************************************************/ /** * @brief This function handles RTC Auto wake-up interrupt request. * @param None * @retval None */ void TIM16_IRQHandler(void) { GPIO_InitTypeDef GPIO_InitStructure; uint16_t temp; TIM16->SR&= ~(1<<0); //清除中断标志;UIF counter_cycle++; if(counter_cycle%2==1) { LED_ON; if(((atm<45)||(atm>155))&&((o2P<450)||(o2P>1550))) { BEEP_ON; } } else { LED_OFF; BEEP_OFF; } if(counter_cycle==20) { TIM14->CR1 = 0; // reset command register 1 TIM14->ARR = 20*FCLK_H_MHZ-1; // 30ms TIM14->CR1 |= 1<<0; // 启动timer2 } // if(rx_flag>3) // { // DMA_Cmd(DMA1_Channel5, DISABLE); /* Disable DMA1 Channel4 transfer */ // DMA1_Channel5->CMAR = (u32)&USART1_RXbuffer; // DMA1_Channel5->CNDTR=USART1_RXtotal; // DMA_Cmd(DMA1_Channel5, ENABLE); /* Enable DMA1 Channel4 transfer */ // } flag_menu = 1; } void TIM14_IRQHandler(void) { uint8_t i; TIM14->SR&= ~(1<<0); //清除中断标志;UIF if(counter_cycle>=20) //重置DMA { DMA_Cmd(DMA1_Channel3, DISABLE); /* Disable DMA1 Channel4 transfer */ DMA1_Channel3->CMAR = (u32)&USART1_RXbuffer; DMA1_Channel3->CNDTR=USART1_RXtotal; DMA_Cmd(DMA1_Channel3, ENABLE); /* Enable DMA1 Channel4 transfer */ } else { DMA_Cmd(DMA1_Channel3, DISABLE); /* Disable DMA1 Channel4 transfer */ } if(sensor_num<64) { on_off(sensor_num); //此处有BUG for(i=0;i<100;i++){}; sensor_num++; //每隔25ms查询一次,如果没有收到数据,则不报送 USART1_TXbuffer[0] = 0x11; USART1_TXbuffer[1] = 0x01; USART1_TXbuffer[2] = 0x01; USART1_TXbuffer[3] = 0xED; DMA_Cmd(DMA1_Channel2, DISABLE); DMA1_Channel2->CMAR = (u32)&USART1_TXbuffer; DMA1_Channel2->CNDTR = USART1_TXtotal; //DMA通道的DMA缓存的大小 DMA_Cmd(DMA1_Channel2, ENABLE); } else sensor_num = 0; cntr_tim14++; display_flag = 1; } void TIM3_IRQHandler(void) { TIM3->SR&= ~(1<<0); //清除中断标志;UIF } /** * @brief This function handles DMA1 Channel 1 interrupt request. * @param None * @retval None */ void DMA1_Channel4_5_IRQHandler(void) { if(DMA_GetITStatus(DMA1_IT_TC4)) { DMA_ClearITPendingBit(DMA1_IT_GL4); //清除DMA通道4的全部中断标志位; DMA_Cmd(DMA1_Channel4, DISABLE); /* Enable DMA1 Channel4 transfer */ } if(DMA_GetITStatus(DMA1_IT_TC5)) { DMA_ClearITPendingBit(DMA1_IT_GL5); // USART_DMACmd(USART1,USART_DMAReq_Tx,DISABLE); //USART1 关闭DMA发送使能; /*--------发送数据前先更新接收DMA防止接收前的干扰*/ } DMA_Cmd(DMA1_Channel5, DISABLE); /* Disable DMA1 Channel4 transfer */ DMA1_Channel5->CMAR = (u32)&USART2_RXbuffer; DMA1_Channel5->CNDTR=USART2_RXtotal; DMA_Cmd(DMA1_Channel5, ENABLE); /* Enable DMA1 Channel4 transfer */ } //------------------------------------------------------------------------------ // DMA1_Channel2 Interrupt Handler ----TIM1_CH1的PWM输入捕获比较; //------------------------------------------------------------------------------ //void DMA1_Channel2_IRQHandler (void) void DMA1_Channel2_3_IRQHandler (void) { uint8_t temp, i; uint16_t temp_o2c; if(DMA_GetITStatus(DMA1_IT_TC2)) { DMA_ClearITPendingBit(DMA1_IT_GL2); //清除DMA通道的中断标志位; DMA_Cmd(DMA1_Channel2, DISABLE); /* Enable DMA1 Channel4 transfer */ } if(DMA_GetITStatus(DMA1_IT_TC3)) { DMA_ClearITPendingBit(DMA1_IT_GL3); //清除DMA通道的中断标志位; rx_flag++; temp = 0; for(i=0; i<12; i++) temp += USART1_RXbuffer[i]; if((temp==0)&&(USART1_RXbuffer[0]==0x16)&&(USART1_RXbuffer[1]==0x09)&&(USART1_RXbuffer[2]==0x01)) { o2c = USART1_RXbuffer[3]*256+USART1_RXbuffer[4]; o2RH = USART1_RXbuffer[5]*256+USART1_RXbuffer[6]; o2t = USART1_RXbuffer[7]*256+USART1_RXbuffer[8]; o2P = USART1_RXbuffer[9]*256+USART1_RXbuffer[10]; rx_flag = 0; } if((display_flag)&&(counter_cycle>20)) { report2_format(); auto2_sending(); display_flag = 0; } } DMA_Cmd(DMA1_Channel3, DISABLE); /* Disable DMA1 Channel4 transfer */ DMA1_Channel3->CMAR = (u32)&USART1_RXbuffer; DMA1_Channel3->CNDTR=USART1_RXtotal; DMA_Cmd(DMA1_Channel3, ENABLE); /* Enable DMA1 Channel4 transfer */ } /*void PPP_IRQHandler(void) { }*/ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 根据上面三个.c文件,增加以下功能串口2是PA2(TX)PA3(RX),串口1是PA9(TX)PA10(RX),检测板接收到电脑发送启动指令FF FF 10 00 00 25 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 00 00 FF FF后将连接传感器的串口1波特率设置为9600,DMA接收12个字节,发送4个字节,并打开电源,等待5秒钟后,向每个传感器连续发送2遍11 AA 55 F0,四个字节每遍间隔时间5秒,发送2遍之后重新设置串口1波特率为250000,DMA接收30个字节,发送30个字节.接收到以下指令后浓度封底:0A 0B AA 01 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 01 02 03 04 FF 浓度不封底:0A 0B AA 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 01 02 03 04 FF 流量0点校准:FF FF 10 00 00 8E 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 00 00 FF FF 高浓度校准:FF FF 10 00 00 7E 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 42 B7 D1 EC FF FF 流量校准:FF FF 10 00 00 8D 00 1E 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 00 00 FF FF 报送数据:FF FF 10 00 00 22 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 00 00 FF FF 直接通过串口1发送给传感器,并接收传感器回复的数据,数据校验要做好 通过串口2发送给电脑,这个是检测板的代码,其他功能不变,只改变,需要改变的部分,屏蔽的部分不要删除,计时用定时器,分别生成三个,c文件
11-01
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vx cr_8118

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值