[25-5]解决 江协STM32 Keil编译报错 4 Error(s), 0 Warning(s) , Start/core_cm3.c(445): error: non-ASM state ...

报错如图所示:

原因已经有很多前辈大佬的解释,不再赘述,本文仅作简单补充。

若不想更换编译器版本,就需要更换编译头文件,主要参考这篇文章:STM32 Keil编译core_cm3.c报错解决办法_keil里面出现core-m3-CSDN博客

最新版本(25-5)MDK的头文件路径如下:(Keil安装路径)...\ARM\Packs\ARM\CMSIS\6.1.0\CMSIS\Core\Include

对于该版本MDK,似乎未能据原文找到 cmsis_armcc.h 头文件,若仅更换下面四个文件并删除 core_cm3.c,一些情况下已经能正常编译,而本人在编译时仍遇到如下问题:( 2 Error(s), 0 Warning(s). )

如图所示,原因是缺失了cmsis_armclang_m.h文件。解决方法很简单,继续复制并添加编译器路径下m-profile文件夹内的cmsis_armclang_m.h文件到项目即可。需要注意的是,应保留m-profile文件夹包含关系不变。可以直接复制该文件夹,并删除其下除cmsis_armclang_m.h外的其他文件,再在Keil内按此路径关系包含该文件。再进行编译已无报错。

*** Using Compiler 'V6.7', folder: 'G:\DanPianJi\Keil\ARM\ARMCLANG\Bin' Rebuild target 'Target 1' Libary/stm32f10x_bkp.c(23): warning: In file included from... ./Libary/stm32f10x_bkp.h(32): warning: In file included from... ./start\stm32f10x.h(478): warning: In file included from... ./start/core_cm3.h(950): error: unknown register name 'basepri' in asm register uint32_t __regBasePri __ASM("basepri"); ^ ./start/core_cm3.h(963): error: unknown register name 'basepri' in asm register uint32_t __regBasePri __ASM("basepri"); ^ ./start/core_cm3.h(976): error: unknown register name 'primask' in asm register uint32_t __regPriMask __ASM("primask"); ^ ./start/core_cm3.h(989): error: unknown register name 'primask' in asm register uint32_t __regPriMask __ASM("primask"); ^ ./start/core_cm3.h(1002): error: unknown register name 'faultmask' in asm register uint32_t __regFaultMask __ASM("faultmask"); ^ ./start/core_cm3.h(1015): error: unknown register name 'faultmask' in asm register uint32_t __regFaultMask __ASM("faultmask"); ^ ./start/core_cm3.h(1028): error: unknown register name 'control' in asm register uint32_t __regControl __ASM("control"); ^ ./start/core_cm3.h(1041): error: unknown register name 'control' in asm register uint32_t __regControl __ASM("control"); ^ ./start/core_cm3.h(1724): warning: implicit declaration of function '__dsb' is invalid in C99 [-Wimplicit-function-declaration] __DSB(); /* Ensure completion of memory access */ ^ ./start/core_cm3.h(773): note: expanded from macro '__DSB' #define __DSB() __dsb(0) ^ ./start/core_cm3.h(1724): warning: this function declaration is not a prototype [-Wstrict-prototypes] ./start/core_cm3.h(773): note: expanded from macro '__DSB' #define __DSB() __dsb(0) ^ Libary/stm32f10x_bkp.c(137): warning: implicit declaration of function 'assert_param' is invalid in C99 [-Wimplicit-function-declaration] assert_param(IS_BKP_TAMPER_PIN_LEVEL(BKP_TamperPinLevel)); ^ Libary/stm32f10x_bkp.c(137): warning: this function declaration is not a prototype [-Wstrict-prototypes] 4 warnings and 8 errors generated. compiling stm32f10x_bkp.c... Libary/stm32f10x_adc.c(23): warning: In file included from... ./Libary/stm32f10x_adc.h(32): warning: In file included from... ./start\stm32f10x.h(478): warning: In file included from... ./start/core_cm3.h(950): error: unknown register name 'basepri' in asm register uint32_t __regBasePri __ASM("basepri"); ^ ./start/core_cm3.h(963): error: unknown register name 'basepri' in asm register uint32_t __regBasePri __ASM("basepri"); ^ ./start/core_cm3.h(976): error: unknown register name 'primask' in asm register uint32_t __regPriMask __ASM("primask"); ^ ./start/core_cm3.h(989): error: unknown register name 'primask' in asm register uint32_t __regPriMask __ASM("primask"); ^ ./start/core_cm3.h(1002): error: unknown register name 'faultmask' in asm register uint32_t __regFaultMask __ASM("faultmask"); ^ ./start/core_cm3.h(1015): error: unknown register name 'faultmask' in asm register uint32_t __regFaultMask __ASM("faultmask"); ^ ./start/core_cm3.h(1028): error: unknown register name 'control' in asm register uint32_t __regControl __ASM("control"); ^ ./start/core_cm3.h(1041): error: unknown register name 'control' in asm register uint32_t __regControl __ASM("control"); ^ ./start/core_cm3.h(1724): warning: implicit declaration of function '__dsb' is invalid in C99 [-Wimplicit-function-declaration] __DSB(); /* Ensure completion of memory access */ ^ ./start/core_cm3.h(773): note: expanded from macro '__DSB'
06-19
<think>根据提供的项目结构,我们需要为每个目录和文件填充代码。下面将按照项目结构逐一编写每个关键文件的代码,并给出必要的解释。###1.核心CMSIS文件(CORE/)####core_cm3.h这是CMSIS的核心头文件,通常不需要修改,直接使用标准文件。####core_cm3.c同样,这是CMSIS的核心实现文件,直接使用标准文件。####startup_stm32f10x_md.s启动文件,针对中等容量STM32F10x设备。这里只展示部分内容,完整文件较长。```assembly;启动文件-中等容量STM32F10x设备;定义堆栈大小Stack_SizeEQU0x00000400AREASTACK,NOINIT,READWRITE,ALIGN=3Stack_MemSPACEStack_Size__initial_sp;堆区域Heap_SizeEQU0x00000200AREAHEAP,NOINIT,READWRITE,ALIGN=3__heap_baseHeap_MemSPACEHeap_Size__heap_limitPRESERVE8THUMB;向量表AREARESET,DATA,READONLYEXPORT__VectorsEXPORT__Vectors_EndEXPORT__Vectors_Size__VectorsDCD__initial_sp;栈顶DCDReset_Handler;复位处理DCDNMI_Handler;NMI处理DCDHardFault_Handler;硬件错误处理;...其他中断向量...DCDTIM3_IRQHandler;TIM3全局中断DCDUSART1_IRQHandler;USART1全局中断;...更多中断向量...__Vectors_End__Vectors_SizeEQU__Vectors_End-__VectorsAREA|.text|,CODE,READONLY;复位处理Reset_HandlerPROCEXPORTReset_Handler[WEAK]IMPORT__mainIMPORTSystemInitLDRR0,=SystemInitBLXR0LDRR0,=__mainBXR0ENDP;默认中断处理NMI_HandlerPROCEXPORTNMI_Handler[WEAK]B.ENDP;...其他默认中断处理...;用户中断处理-使用弱定义TIM3_IRQHandlerPROCEXPORTTIM3_IRQHandler[WEAK]B.ENDPUSART1_IRQHandlerPROCEXPORTUSART1_IRQHandler[WEAK]B.ENDPALIGN;用户栈和堆初始化IF:DEF:__MICROLIBEXPORT__initial_spEXPORT__heap_baseEXPORT__heap_limitELSEIMPORT__use_two_region_memoryEXPORT__user_initial_stackheap__user_initial_stackheapLDRR0,=Heap_MemLDRR1,=(Stack_Mem+Stack_Size)LDRR2,=(Heap_Mem+Heap_Size)LDRR3,=Stack_MemBXLRALIGNENDIFEND```####system_stm32f10x.c系统时钟初始化,设置系统时钟为72MHz。```c#include"stm32f10x.h"/*系统时钟频率(单位:Hz)*/uint32_tSystemCoreClock=72000000;/***@brief设置系统时钟到72MHz*@paramNone*@retvalNone*/voidSystemInit(void){/*复位RCC时钟配置为默认状态*/RCC->CR|=(uint32_t)0x00000001;/*使能内部高速时钟HSI*/RCC->CFGR&=(uint32_t)0xF8FF0000;/*复位SW,HPRE,PPRE,ADCPRE,MCO*/RCC->CR&=(uint32_t)0xFEF6FFFF;/*复位HSEON,CSSON,PLLON*/RCC->CR&=(uint32_t)0xFFFBFFFF;/*复位HSEBYP*/RCC->CFGR&=(uint32_t)0xFF80FFFF;/*复位PLLSRC,PLLXTPRE,PLLMUL*//*配置外部高速晶振(HSE)*/RCC->CR|=((uint32_t)RCC_CR_HSEON);/*使能HSE*//*等待HSE稳定*/while((RCC->CR&RCC_CR_HSERDY)==0){}/*配置FLASH预取指缓冲和等待状态*/FLASH->ACR=FLASH_ACR_PRFTBE|FLASH_ACR_LATENCY_2;/*HCLK=SYSCLK*/RCC->CFGR|=(uint32_t)RCC_CFGR_HPRE_DIV1;/*PCLK2=HCLK*/RCC->CFGR|=(uint32_t)RCC_CFGR_PPRE2_DIV1;/*PCLK1=HCLK/2*/RCC->CFGR|=(uint32)RCC_CFGR_PPRE1_DIV2;/*配置PLL:PLLCLK=HSE*9=72MHz*/RCC->CFGR&=(uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC|RCC极CFGR_PLLXTPRE|RCC_CFGR_PLLMULL));RCC->CFGR|=(uint32_t)(RCC_CFGR_PLLSRC_HSE|RCC_CFGR_PLLMULL9);/*使能PLL*/RCC->CR|=RCC_CR_PLLON;/*等待PLL稳定*/while((RCC->CR&RCC_CR_PLLRDY)==0){}/*选择PLL作为系统时钟源*/RCC->CFGR&=(uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR|=(uint32_t)RCC_CFGR_SW_PLL;/*等待时钟切换完成*/while((RCC->CFGR&(uint32_t)RCC_CFGR_SWS)!=(uint32_t)0x08){}SystemCoreClock=72000000;//更新系统时钟频率}```###2.硬件驱动(HARDWARE/)####LED驱动(LED/)#####led.h```c#ifndef__LED_H#define__LED_H#include"stm32f10x.h"#defineLED_PORTGPIOB#defineLED_PINGPIO_Pin_5voidLED_Init(void);voidLED_On(void);voidLED_Off(void);voidLED_Toggle(void);#endif/*__LED_H*/```#####led.c```c#include"led.h"voidLED_Init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitStructure.GPIO_Pin=LED_PIN;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(LED_PORT,&GPIO_InitStructure);LED_Off();//初始关闭LED}voidLED_On(void){GPIO_ResetBits(LED_PORT,LED_PIN);//低电平点亮}voidLED_Off(void){GPIO_SetBits(LED_PORT,LED_PIN);//高电平熄灭}voidLED_Toggle(void){LED_PORT->ODR^=LED_PIN;}```####DS18B20温度传感器(DS18B20/)#####ds18b20.h```c#ifndef__DS18B20_H#define__DS18B20_H#include"stm32f10x.h"#defineDS18B20_PORTGPIOA#defineDS18B20_PINGPIO_Pin_0voidDS18B20_Init(void);floatDS18B20_ReadTemp(void);#endif/*__DS18B20_H*/```#####ds18b20.c```c#include"ds18b20.h"#include"delay.h"staticvoidDS18B20_Reset(void);staticvoidDS18B20_WriteByte(uint8_tdat);staticuint8_tDS18B20_ReadByte(void);staticuint8_tDS18B20_Check(void);voidDS18B20_Init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);//拉高总线GPIO_SetBits(DS18B20_PORT,DS18B20_PIN);}//复位DS18B20staticvoidDS18B20_Reset(void){GPIO_InitTypeDefGPIO_InitStructure;//设置为输出模式GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);//拉低总线480usGPIO_ResetBits(DS18B20_PORT,DS18B20_PIN);delay_us(480);//释放总线(拉高)GPIO_SetBits(DS18B20_PORT,DS18B20_PIN);delay_us(60);//设置为输入模式GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);//等待DS18B20应答while(GPIO_ReadInputDataBit(DS18B20_PORT,DS18B20_PIN)==Bit_RESET);while(GPIO_ReadInputDataBit(DS18B20_PORT,DS18B20_PIN)==Bit_SET);delay_us(480);}//写一个字节到DS18B20staticvoidDS18B20_WriteByte(uint8_tdat){GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);for(inti=0;i<8;i++){GPIO_ResetBits(DS18B20_PORT,DS18B20_PIN);delay_us(2);if(dat&0x01){GPIO_SetBits(DS18B20_PORT,DS18B20_PIN);}else{GPIO_ResetBits(DS18B20_PORT,DS18B20_PIN);}delay_us(60);GPIO_SetBits(DS18B20_PORT,DS18B20_PIN);dat>>=1;delay_us(2);}}//从DS18B20读取一个字节staticuint8_tDS18B20_ReadByte(void){GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);uint8_tvalue=0;for(inti=0;i<8;i++){GPIO_ResetBits(极DS18B20_PORT,DS18B20_PIN);delay_us(2);GPIO_SetBits(DS18B20_PORT,DS18B20_PIN);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);delay_us(8);if(GPIO_ReadInputDataBit(DS18B20_PORT,DS18B20_PIN)==Bit_SET){value|=(1<<i);}delay_us(50);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);}returnvalue;}floatDS18B20_ReadTemp(void){uint8_ttemp_l,temp_h;shorttemp;floattemperature;DS18B20_Reset();DS18B20_WriteByte(0xCC);//跳过ROMDS18B20_WriteByte(0x44);//启动温度转换delay_ms(750);//等待转换完成DS18B20_Reset();DS18B20_WriteByte(0xCC);//跳过ROMDS18B20_WriteByte(0xBE);//读取温度寄存器temp_l=DS18B20_ReadByte();temp_h=DS18B20_ReadByte();temp=(temp_h<<8)|temp_l;temperature=(float)temp/16.0;returntemperature;}```####数码管驱动(SMG/)#####smg.h```c#ifndef__SMG_H#define__SMG_H#include"stm32f10x.h"#defineHC595_PORTGPIOA#defineHC595_DATAGPIO_Pin_1#defineHC595_CLKGPIO_Pin_2#defineHC595_LATCHGPIO_Pin_3voidSMG_Init(void);voidSMG_Display(uint8_t*buf);#endif/*__SMG_H*/```#####smg.c```c#include"smg.h"#include"delay.h"//数码管段码表(共阴)constuint8_tSEGMENT_CODES[]={0x3F,//00x06,//10x5B,//20x4F,//30x66,//40x6D,//50x7D,//60x07,//70x7F,//80x6F//9};voidSMG_Init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitStructure.GPIO_Pin=HC595_DATA|HC595_CLK|HC595_LATCH;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(HC595_PORT,&GPIO_InitStructure);GPIO_SetBits(HC595_PORT,HC595_DATA|HC595_CLK|HC595_LATCH);}//发送一个字节到74HC595staticvoidHC595_SendByte(uint8_tdata){for(uint8_ti=0;i<8;i++){if(data&0x80){GPIO_SetBits(HC595_PORT,HC595_DATA);}else{GPIO_ResetBits(HC595_PORT,HC595_DATA);}data<<=1;//上升沿发送数据GPIO_ResetBits(HC595_PORT,HC595_CLK);delay_us(5);GPIO_SetBits(HC595_PORT,HC595_CLK);delay_us(5);}}//数码管显示函数voidSMG_Display(uint8_t*buf){for(uint8_ti=0;i<4;i++){//发送段码HC595_SendByte(SEGMENT_CODES[buf[i]]);//发送位选(共阴数码管,低电平选中)HC595_SendByte(~(1<<i));//锁存数据GPIO_ResetBits(HC595_PORT,HC595_LATCH);delay_us(5);GPIO_SetBits(HC595_PORT,HC595_LATCH);delay_ms(2);//短暂延时,保证显示稳定}}```####蜂鸣器驱动(BEEP/)#####beep.h```c#ifndef__BEEP_H#define__BEEP_H#include"stm32f10x.h"#defineBEEP_PORTGPIOB#defineBEEP_PINGPIO_Pin_8voidBEEP_Init(void);voidBEEP_On(void);voidBEEP_Off(void);#endif/*__BEEP_H*/```#####beep.c```c#include"beep.h"voidBEEP_Init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitStructure.GPIO_Pin=BEEP_PIN;GPIO极InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(BEEP_PORT,&GPIO_InitStructure);BEEP_Off();}voidBEEP_On(void){GPIO_SetBits(BEEP_PORT,BEEP_PIN);}voidBEEP_Off(void){GPIO_ResetBits(BEEP_PORT,BEEP_PIN);}```###3.标准外设库(STM32F10x_PWLb/)这部分代码通常不需要修改,直接使用ST官方提供的标准外设库文件。确保在工程中包含所有必要的外设源文件。###4.用户代码(USER/)####main.c```c#include"stm32f10x.h"#include"led.h"#include"ds18b20.h"#include"smg.h"#include"beep.h"#include"delay.h"#include"stm32f10x_tim.h"#include"stm32f10x_usart.h"floatcurrent_temp=0;floattemp_max=30.0;//报警温度阈值uint8_talarm_flag=0;uint8_tdisplay_buffer[4]={0};//数码管显示缓冲区//函数声明voidRCC_Configuration(void);voidGPIO_Configuration(void);voidTIM3_Init(void);voidUSART1_Init(uint32_tbaudrate);voidUpdate_DisplayBuffer(void);intmain(void){SystemInit();RCC_Configuration();GPIO_Configuration();TIM3_Init();USART1_Init(115200);delay_init();LED_Init();DS18B20_Init();SMG_Init();BEEP_Init();//启用中断NVIC_EnableIRQ(TIM3_IRQn);TIM_Cmd(TIM3,ENABLE);while(1){current_temp=DS18B20_ReadTemp();Update_DisplayBuffer();//温度报警if(current_temp>temp_max){BEEP_On();alarm_flag=1;}else{BEEP_Off();alarm_flag=0;}//串口打印温度printf("CurrentTemp:%.1fC\r\n",current_temp);delay_ms(500);LED_Toggle();}}//更新显示缓冲区voidUpdate_DisplayBuffer(void){uint8_ttemp=(uint8_t)(current_temp*10);display_buffer[0]=temp/100;//百位(通常为0)display_buffer[1]=(temp/10)%10;//十位display_buffer[2]=temp%10;//个位display_buffer[3]=10;//小数点(自定义段码)}//定时器3中断服务函数(用于数码管动态扫描)voidTIM3_IRQHandler(void){if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET){SMG_Display(display_buffer);TIM_ClearITPendingBit(TIM3,TIM_IT_Update);}}//串口1中断服务函数voidUSART1_IRQHandler(void){if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){uint8_tdata=USART_ReceiveData(USART1);//处理接收数据}}//重写fputc函数,支持printfintfputc(intch,FILE*f){USART_SendData(USART1,(uint8_t)ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);returnch;}//时钟配置voidRCC_Configuration(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO|RCC_APB2Periph_USART1,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);}//GPIO配置voidGPIO_Configuration(void){//配置USART1TX(PA9)RX(PA10)GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStructure);}//定时器3初始化(用于数码管动态扫描)voidTIM3_Init(void){TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;NVIC_InitTypeDefNVIC_InitStructure;//定时器3时钟使能RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//定时器3基本配置TIM_TimeBaseStructure.TIM_Period=1000;//自动重装载值TIM_TimeBaseStructure.TIM_Prescaler=72-1;//预分频器TIM_TimeBaseStructure.TIM_ClockDivision=0;TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//使能定时器3更新中断TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//配置定时器3中断优先级NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);}//USART1初始化voidUSART1_Init(uint32_tbaudrate){USART_InitTypeDefUSART_InitStructure;USART_InitStructure.USART_BaudRate=baudrate;USART_InitStructure.USART_WordLength=USART_WordLength_8b;USART_InitStructure.USART_StopBits=USART_StopBits_1;USART_InitStructure.USART_Parity=USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_Init(USART1,&USART_InitStructure);USART_Cmd(USART1,ENABLE);}```####stm32f10x_conf.h```c#ifndef__STM32F10X_CONF_H#define__STM32F10X_CONF_H/*使用标准外设驱动*/#defineUSE_STDPERIPH_DRIVER/*包含所需的外设头文件*/#include"stm32f10x_gpio.h"#include"stm32f10x_rcc.h"#include"stm32f10x_tim.h"#include"stm32f10x_usart.h"#include"misc.h"//用于NVIC配置/*断言配置-调试阶段启用*///#defineUSE_FULL_ASSERT#ifdefUSE_FULL_ASSERT#defineassert_param(expr)((expr)?(void)0:assert_failed((uint8_t*)__FILE__,__LINE__))voidassert_failed(uint8_t*file,uint32_tline);#else#defineassert_param(expr)((void)0)#endif#endif/*__STM32F10X_CONF_H*/```####stm32f10x_it.h```c#ifndef__STM32F10X_IT_H#define__STM32F10X_IT_H#include"stm32f10x.h"voidNMI_Handler(void);voidHardFault_Handler(void);voidMemManage_Handler(void);voidBusFault_Handler(void);voidUsageFault_Handler(void);voidSVC_Handler(void);voidDebugMon_Handler(void);voidPendSV_Handler(void);voidSysTick_Handler(void);voidTIM3_IRQHandler(void);voidUSART1_IRQHandler(void);#endif/*__STM32F10X_IT_H*/```####stm32f10x_it.c```c#include"stm32f10x_it.h"voidNMI_Handler(void){}voidHardFault_Handler(void){while(1);}voidMemManage_Handler(void){while(1);}voidBusFault_Handler(void){while(1);}voidUsageFault_Handler(void){while(1);}voidSVC_Handler(void){}voidDebugMon_Handler(void){}voidPendSV_Handler(void){}voidSysTick_Handler(void){}//定时器3中断服务函数voidTIM3_IRQHandler(void){//在main.c中实现}//串口1中断服务函数voidUSART1_IRQHandler(void){//在main.c中实现}```###5.延时函数(USER/delay.c)####delay.h```c#ifndef__DELAY_H#define__DELAY_H#include"stm32f10x.h"voiddelay_init(void);voiddelay_us(uint32_tus);voiddelay_ms(uint16_tms);#endif/*__DELAY_H*/```####delay.c```c#include"delay.h"staticuint8_tfac_us=0;staticuint16_tfac_ms=0;voiddelay_init(){SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//选择外部时钟HCLK/8fac_us=SystemCoreClock/8000000;//为1us计数fac_ms=(uint16_t)fac_us*1000;//为1ms计数}voiddelay_us(uint32_tnus){uint32_ttemp;SysTick->LOAD=nus*fac_us;//加载计数值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;//清空计数器}voiddelay_ms(uint16_tnms){uint32_ttemp;SysTick->LOAD=(uint32_t)nms*fac_ms;//加载计数值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;//清空计数器}```###项目构建说明1.**包含路径**:确保包含所有头文件目录2.**预处理器定义**:添加`USE_STDPERIPH_DRIVER`和`STM32F10X_MD`(根据芯片容量选择)3.**源文件分组**:将上述所有源文件添加到工程中###总结以上代码构成了一个完整的STM32温度计项目,包括:-系统初始化-外设驱动(LED、数码管、蜂鸣器、DS18B20-定时器用于数码管动态扫描-串口用于调试输出-温度采集与显示§§相关问题§§:1.如何优化DS18B20的读取速度?2.数码管动态扫描的原理是什么?3.STM32中如何实现printf重定向?4.如何配置STM32的定时器中断优先级?</think>以下是完整的STM32温度计项目代码实现,按照您提供的文件结构组织。我将为每个目录和文件提供详细代码和注释。 ### 项目结构代码实现 ```c /* 温度计项目/ ├── CORE/ # 核心CMSIS文件 │ ├── core_cm3.c # ARM Cortex-M3核心支持 │ ├── core_cm3.h │ ├── startup_stm32f10x_md.s # 启动文件(根据芯片容量选择) │ └── system_stm32f10x.c # 系统时钟初始化 ├── HARDWARE/ # 硬件驱动 │ ├── LED/ # LED驱动 │ │ ├── led.c │ │ └── led.h │ ├── DS18B20/ # 温度传感器 │ │ ├── ds18b20.c │ │ └── ds18b20.h │ ├── SMG/ # 数码管驱动 │ │ ├── smg.c │ │ └── smg.h │ └── BEEP/ # 蜂鸣器驱动 │ ├── beep.c │ └── beep.h ├── STM32F10x_PWLb/ # 标准外设库 │ ├── inc/ # 外设头文件 │ └── src/ # 外设实现 └── USER/ # 用户代码 ├── main.c # 主程序 ├── stm32f10x_conf.h # 库配置文件 ├── stm32f10x_it.c # 中断服务 └── stm32f10x_it.h # 中断头文件 */ ``` ### 1. 核心CMSIS文件 (CORE/) #### core_cm3.h ```c /**************************************************************************//** * @file core_cm3.h * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File * @version V4.30 * @date 20. October 2015 ******************************************************************************/ #ifndef __CORE_CM3_H_GENERIC #define __CORE_CM3_H_GENERIC // 定义处理器特性 #define __CORTEX_M (0x03) /* Cortex-M3核心 */ // 内存映射定义 #define SCS_BASE (0xE000E000UL) /* 系统控制空间基地址 */ #define SysTick_BASE (SCS_BASE + 0x0010UL) /* SysTick基地址 */ #define NVIC_BASE (SCS_BASE + 0x0100UL) /* NVIC基地址 */ // 中断号定义 typedef enum IRQn { NonMaskableInt_IRQn = -14, /* 不可屏蔽中断 */ MemoryManagement_IRQn = -12, /* 内存管理故障 */ BusFault_IRQn = -11, /* 总线故障 */ UsageFault_IRQn = -10, /* 用法故障 */ SVCall_IRQn = -5, /* SVCall中断 */ DebugMonitor_IRQn = -4, /* 调试监视器 */ PendSV_IRQn = -2, /* PendSV中断 */ SysTick_IRQn = -1, /* SysTick中断 */ // 外设中断 WWDG_IRQn = 0, /* 窗口看门狗中断 */ PVD_IRQn = 1, /* PVD通过EXTI检测中断 */ TAMPER_IRQn = 2, /* 篡改中断 */ RTC_IRQn = 3, /* RTC全局中断 */ FLASH_IRQn = 4, /* Flash全局中断 */ RCC_极IRQn = 5, /* RCC全局中断 */ EXTI0_IRQn = 6, /* EXTI线0中断 */ EXTI1_IRQn = 7, /* EXTI线1中断 */ EXTI2_IRQn = 8, /* EXTI线2中断 */ EXTI3_IRQn = 9, /* EXTI线3中断 */ EXTI4_IRQn = 10, /* EXTI线4中断 */ DMA1_Channel1_IRQn = 11, /* DMA1通道1全局中断 */ DMA1_Channel2_IRQn = 12, /* DMA1通道2全局中断 */ DMA1_Channel3_IRQn = 13, /* DMA1通道3全局中断 */ DMA1_Channel4_IRQn = 14, /* DMA1通道4全局中断 */ DMA1_Channel5_IRQn = 15, /* DMA1通道5全局中断 */ DMA1_Channel6_IRQn = 16, /* DMA1通道6全局中断 */ DMA1_Channel7_IRQn = 17, /* DMA1通道7全局中断 */ ADC1_2_IRQn = 18, /* ADC1和ADC2全局中断 */ USB_HP_CAN1_TX_IRQn = 19, /* USB高优先级或CAN1 TX中断 */ USB_LP_CAN1_RX0_IRQn = 20, /* USB低优先级或CAN1 RX0中断 */ CAN1_RX1_IRQn = 21, /* CAN1 RX1中断 */ CAN1_SCE_IRQn = 22, /* CAN1 SCE中断 */ EXTI9_5_IRQn = 23, /* EXTI线[9:5]中断 */ TIM1_BRK_IRQn = 24, /* TIM1刹车中断 */ TIM1_UP_IRQn = 25, /* TIM1更新中断 */ TIM1_TRG_COM_IRQn = 26, /* TIM1触发和通信中断 */ TIM1_CC_IRQn = 27, /* TIM1捕获比较中断 */ TIM2_IRQn = 28, /* TIM2全局中断 */ TIM3_IRQn = 29, /* TIM3全局中断 */ TIM4_IRQn = 30, /* TIM4全局中断 */ I2C1_EV_IRQn = 31, /* I2C1事件中断 */ I2C1_ER_IRQn = 32, /* I2C1错误中断 */ I2C2_EV_IRQn = 33, /* I2C2事件中断 */ I2C2_ER_IRQn = 34, /* I2C2错误中断 */ SPI1_IRQn = 35, /* SPI1全局中断 */ SPI2_IRQn = 36, /* SPI2全局中断 */ USART1_IRQn = 37, /* USART1全局中断 */ USART2_IRQn = 38, /* USART2全局中断 */ USART3_IRQn = 39, /* USART3全局中断 */ EXTI15_10_IRQn = 40, /* EXTI线[15:10]中断 */ RTCAlarm_IRQn = 41, /* RTC闹钟通过EXTI线中断 */ USBWakeUp_IRQn = 42, /* USB唤醒通过EXTI线中断 */ TIM8_BRK_IRQn = 43, /* TIM8刹车中断 */ TIM8_UP_IRQn = 44, /* TIM8更新中断 */ TIM8_TRG_COM_IRQn = 45, /* TIM8触发和通信中断 */ TIM8_CC_IRQn = 46, /* TIM8捕获比较中断 */ ADC3_IRQn = 47, /* ADC3全局中断 */ FSMC_IRQn = 48, /* FSMC全局中断 */ SDIO_IRQn = 49, /* SDIO全局中断 */ TIM5_IRQn = 50, /* TIM5全局中断 */ SPI3_IRQn = 51, /* SPI3全局中断 */ UART4_IRQn = 52, /* UART4全局中断 */ UART5_IRQn = 53, /* UART5全局中断 */ TIM6_IRQn = 54, /* TIM6全局中断 */ TIM7_IRQn = 55, /* TIM7全局中断 */ DMA2_Channel1_IRQn = 56, /* DMA2通道1全局中断 */ DMA2_Channel2_IRQn = 57, /* DMA2通道2全局中断 */ DMA2_Channel3_IRQn = 58, /* DMA2通道3全局中断 */ DMA2_Channel4_5_IRQn = 59 /* DMA2通道45全局中断 */ } IRQn_Type; // NVIC寄存器结构 typedef struct { __IO uint32_t ISER[8]; /* 中断使能寄存器 */ uint32_t RESERVED0[24]; __IO uint32_t ICER[8]; /* 中断清除寄存器 */ /* ... 其他寄存器 ... */ } NVIC_Type; // 其他核心寄存器定义... #endif /* __CORE_CM3_H_GENERIC */ ``` #### system_stm32f10x.c ```c #include "stm32f10x.h" /* 系统时钟频率 (单位: Hz) */ uint32_t SystemCoreClock = 72000000; /** * @brief 设置系统时钟到72MHz * @param None * @retval None */ void SystemInit(void) { /* 复位RCC时钟配置为默认状态 */ RCC->CR |= (uint32_t)0x00000001; /* 使能内部高速时钟HSI */ RCC->CFGR &= (uint32_t)0xF8FF0000; /* 复位SW, HPRE, PPRE, ADCPRE, MCO */ RCC->CR &= (uint32_t)0xFEF6FFFF; /* 复位HSEON, CSSON, PLLON */ RCC->CR &= (uint32_t)0xFFFBFFFF; /* 复位HSEBYP */ RCC->CFGR &= (uint32_t)0xFF80FFFF; /* 复位PLLSRC, PLLXTPRE, PLLMUL */ /* 配置外部高速晶振(HSE) */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* 使能HSE */ /* 等待HSE稳定 */ while ((RCC->CR & RCC_CR_HSERDY) == 0) {} /* 配置FLASH预取指缓冲和等待状态 */ FLASH->ACR = FLASH_AC极_PRFTBE | FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK/2 */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; /* 配置PLL: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); /* 使能PLL */ RCC->CR |= RCC_CR_PLLON; /* 等待PLL稳定 */ while ((RCC->CR & RCC_CR_PLLRDY) == 0) {} /* 选择极PLL作为系统时钟源 */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* 等待时钟切换完成 */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) {} SystemCoreClock = 72000000; // 更新系统时钟频率 } ``` ### 2. 硬件驱动 (HARDWARE/) #### LED驱动 (LED/) ##### led.h ```c #ifndef __LED_H #define __LED_H #include "stm32f10x.h" #define LED_PORT GPIOB #define LED_PIN GPIO_Pin_5 void LED_Init(void); void LED_On(void); void LED_Off(void); void LED_Toggle(void); #endif /* __LED_H */ ``` ##### led.c ```c #include "led.h" void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_PORT, &GPIO_InitStructure); LED_Off(); // 初始关闭LED } void LED_On(void) { GPIO_ResetBits(LED_PORT, LED_PIN); // 低电平点亮 } void LED_Off(void) { GPIO_SetBits(LED_PORT, LED_PIN); // 高电平熄灭 } void LED_Toggle(void) { LED_PORT->ODR ^= LED_PIN; } ``` #### DS18B20温度传感器 (DS18B20/) ##### ds18b20.h ```c #ifndef __DS18B20_H #define __DS18B20_H #include "stm32f10x.h" #define DS18B20_PORT GPIOA #define DS18B20_PIN GPIO_Pin_0 void DS18B20_Init(void); float DS18B20_ReadTemp(void); #endif /* __DS18B20_H */ ``` ##### ds18b20.c ```c #include "ds18b20.h" #include "delay.h" static void DS18B20_Reset(void); static void DS18B20_WriteByte(uint8_t dat); static uint8_t DS18B20_ReadByte(void); static uint8_t DS18B20_Check(void); void DS18B20_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); // 拉高总线 GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); } // 复位DS18B20 static void DS18B20_Reset(void) { GPIO_InitTypeDef GPIO_InitStructure; // 设置为输出模式 GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); // 拉低总线480us GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN); delay_us(480); // 释放总线(拉高) GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); delay_us(60); // 设置为输入模式 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); // 等待DS18B20应答 while (GPIO_ReadInputDataBit(DS18B20_PORT, DS18B20_PIN) == Bit_RESET); while (GPIO_ReadInputDataBit(DS18B20_PORT, DS18B20_PIN) == Bit_SET); delay_us(480); } // 写一个字节到DS18B20 static void DS18B20_WriteByte(uint8_t dat) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); for (int i = 0; i < 8; i++) { GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN); delay_us(2); if (dat & 0x01) { GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); } else { GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN); } delay_us(60); GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); dat >>= 1; delay_us(2); } } // 从DS18B20读取一个字节 static uint8_t DS18B20_ReadByte(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = DS18B20_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); uint8_t value = 0; for (int i = 0; i < 8; i++) { GPIO_ResetBits(DS18B20_PORT, DS18B20_PIN); delay_us(2); GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); delay_us(8); if (GPIO_ReadInputDataBit(DS18B20_PORT, DS18B20_PIN) == Bit_SET) { value |= (1 << i); } delay_us(50); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(DS18B20_PORT, &GPIO_InitStructure); } return value; } float DS18B20_ReadTemp(void) { uint8_t temp_l, temp_h; short temp; float temperature; DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0x44); // 启动温度转换 delay_ms(750); // 等待转换完成 DS18B20_Reset(); DS18B20_WriteByte(0xCC); // 跳过ROM DS18B20_WriteByte(0xBE); // 读取温度寄存器 temp_l = DS18B20_ReadByte(); temp_h = DS18B20_ReadByte(); temp = (temp_h << 8) | temp_l; temperature = (float)temp / 16.0; return temperature; } ``` #### 数码管驱动 (SMG/) ##### smg.h ```c #ifndef __SMG_H #define __SMG_H #include "stm32f10x.h" #define HC595_PORT GPIOA #define HC595_DATA GPIO_Pin_1 #define HC595_CLK GPIO_Pin_2 #define HC595_LATCH GPIO_Pin_3 void SMG_Init(void); void SMG_Display(uint8_t *buf); #endif /* __SMG_H */ ``` ##### smg.c ```c #include "smg.h" #include "delay.h" // 数码管段码表(共阴) const uint8_t SEGMENT_CODES[] = { 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x07, // 7 0x7F, // 8 0x6F // 9 }; void SMG_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = HC595_DATA | HC595_CLK | HC595_LATCH; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(HC595_PORT, &GPIO_InitStructure); GPIO_SetBits(HC595_PORT, HC595_DATA | HC595_CLK | HC595_LATCH); } // 发送一个字节到74HC595 static void HC595_SendByte(uint8_t data) { for (uint8_t i = 0; i < 8; i++) { if (data & 0x80) { GPIO_SetBits(HC595_PORT, HC595_DATA); } else { GPIO_ResetBits(HC595_PORT, HC595_DATA); } data <<= 1; // 上升沿发送数据 GPIO_ResetBits(HC595_PORT, HC595_CLK); delay_us(5); GPIO_SetBits(HC595_PORT, HC595_CLK); delay_us(5); } } // 数码管显示函数 void SMG_Display(uint8_t *buf) { for (uint8_t i = 0; i < 4; i++) { // 发送段码 HC595_SendByte(SEGMENT_CODES[buf[i]]); // 发送位选(共阴数码管,低电平选中) HC595_SendByte(~(1 << i)); // 锁存数据 GPIO_ResetBits(HC595_PORT, HC595_LATCH); delay_us(5); GPIO_SetBits(HC595_PORT, HC595_LATCH); delay_ms(2); // 短暂延时,保证显示稳定 } } ``` #### 蜂鸣器驱动 (BEEP/) ##### beep.h ```c #ifndef __BEEP_H #define __BEEP_H #include "stm32f10x.h" #define BEEP_PORT GPIOB #define BEEP_PIN GPIO_Pin_8 void BEEP_Init(void); void BEEP_On(void); void BEEP_Off(void); #endif /* __BEEP_H */ ``` ##### beep.c ```c #include "beep.h" void BEEP_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = BEEP_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(BEEP_PORT, &GPIO_InitStructure); BEEP_Off(); } void BEEP_On(void) { GPIO_SetBits(BEEP_PORT, BEEP_PIN); } void BEEP_Off(void) { GPIO_ResetBits(BEEP_PORT, BEEP_PIN); } ``` ### 3. 标准外设库 (STM32F10x_PWLb/) 这部分代码通常不需要修改,直接使用ST官方提供的标准外设库文件。确保在工程中包含所有必要的外设源文件。 ### 4. 用户代码 (USER/) #### main.c ```c #include "stm32f10x.h" #include "led.h" #include "ds18b20.h" #include "smg.h" #include "beep.h" #include "delay.h" #include "stm32f10x_tim.h" #include "stm32f10x_usart.h" float current_temp = 0; float temp_max = 30.0; // 报警温度阈值 uint8_t alarm_flag = 0; uint8_t display_buffer[4] = {0}; // 数码管显示缓冲区 // 函数声明 void RCC_Configuration(void); void GPIO_Configuration(void); void TIM3_Init(void); void USART1_Init(uint32_t baudrate); void Update_DisplayBuffer(void); int main(void) { SystemInit(); RCC_Configuration(); GPIO_Configuration(); TIM3_Init(); USART1_Init(115200); delay_init(); LED_Init(); DS18B20_Init(); SMG_Init(); BEEP_Init(); // 启用中断 NVIC_EnableIRQ(TIM3_IRQn); TIM_Cmd(TIM3, ENABLE); while (1) { current_temp = DS18B20_ReadTemp(); Update_DisplayBuffer(); // 温度报警 if (current_temp > temp_max) { BEEP_On(); alarm_flag = 1; } else { BEEP_Off(); alarm_flag = 极0; } // 串口打印温度 printf("Current Temp: %.1fC\r\n", current_temp); delay_ms(500); LED_Toggle(); } } // 更新显示缓冲区 void Update_DisplayBuffer(void) { uint8_t temp = (uint8_t)(current_temp * 10); display_buffer[0] = temp / 100; // 百位(通常为0) display_buffer[1] = (temp / 10) % 10; // 十位 display_buffer[2] = temp % 10; // 个位 display_buffer[3] = 10; // 小数点(自定义段码) } // 定时器3中断服务函数(用于数码管动态扫描) void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { SMG_Display(display_buffer); TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } } // 串口1中断服务函数 void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t data = USART_ReceiveData(USART1); // 处理接收数据 } } // 重写fputc函数,支持printf int fputc(int ch, FILE *f) { USART_SendData(USART1, (uint8_t) ch); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); return ch; } // 时钟配置 void RCC_Configuration(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); } // GPIO配置 void GPIO_Configuration(void) { // 配置USART1 TX (PA9) RX (PA10) GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); } // 定时器3初始化(用于数码管动态扫描) void TIM3_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; // 定时器3时钟使能 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 定时器3基本配置 TIM_TimeBaseStructure.TIM_Period = 1000; // 自动重装载值 TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 预分频器 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 使能定时器3更新中断 TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 配置定时器3中断优先级 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } // USART1初始化 void USART1_Init(uint32_t baudrate) { USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = baudrate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } ``` #### stm32f10x_conf.h ```c #ifndef __STM32F10X_CONF_H #define __STM32F10X_CONF_H /* 使用标准外设驱动 */ #define USE_STDPERIPH_DRIVER /* 包含所需的外设头文件 */ #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_tim.h" #include "stm32f10x_usart.h" #include "misc.h" // 用于NVIC配置 /* 断言配置 - 调试阶段启用 */ // #define USE_FULL_ASSERT #ifdef USE_FULL_ASSERT #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) void assert_failed(uint8_t* file, uint32_t line); #else #define assert_param(expr) ((void)0) #endif #endif /* __STM32F10X_CONF_H */ ``` #### stm32f10x_it.h ```c #ifndef __STM32F10X_IT_H #define __STM32F10X_IT_H #include "stm32f10x.h" void NMI_Handler(void); void HardFault_Handler(void); void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); void TIM3_IRQHandler(void); void USART1_IRQHandler(void); #endif /* __STM32F10X_IT_H */ ``` #### stm32f10x_it.c ```c #include "stm32f10x_it.h" void NMI_Handler(void) {} void HardFault_Handler(void) { while (1); } void MemManage_Handler(void) { while (1); } void BusFault_Handler(void) { while (1); } void UsageFault_Handler(void) { while (1); } void SVC_Handler(void) {} void DebugMon_Handler(void) {} void PendSV_Handler(void) {} void SysTick_Handler(void) {} // 定时器3中断服务函数 void TIM3_IRQHandler(void) { // 在main.c中实现 } // 串口1中断服务函数 void USART1_IRQHandler(void) { // 在main.c中实现 } ``` ### 项目说明 #### 功能概述 1. **温度采集**:使用DS18B20单总线温度传感器 2. **数据显示**:4位数码管显示当前温度 3. **温度报警**:超过阈值时蜂鸣器报警 4. **调试输出**:通过USART1输出温度数据 5. **状态指示**:LED闪烁指示系统运行 #### 关键组件 1. **定时器TIM3**:用于数码管动态扫描刷新(1kHz中断) 2. **USART1**:115200波特率,用于调试输出 3. **GPIO控制**: - PA0: DS18B20数据线 - PA1-3: 74HC595控制线(数据、时钟、锁存) - PB5: LED指示灯 - PB8: 蜂鸣器控制 - PA9-10: USART1 TX/RX #### 编译配置 1. **芯片型号**:STM32F103C8T6(中等容量) 2. **预处理器定义**: - `USE_STDPERIPH_DRIVER` - `STM32F10X_MD` 3. **包含路径**: - CORE - HARDWARE - STM32F10x_PWLb/inc - USER #### 使用说明 1. 连接硬件: - DS18B20: PA0 - 74HC595: PA1(数据), PA2(时钟), PA3(锁存) - LED: PB5 - 蜂鸣器: PB8 - USART: PA9(TX), PA10(RX) 2. 编译并下载程序 3. 上电后数码管显示当前温度 4. 温度超过30°C时蜂鸣器报警 5. 串口输出温度数据(115200,8,N,1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值