STM32F103 AD 在写完flash后变得不准
STM32F103AD 在写完flash后变得不准经过过测试和不相干IO口设置有关怎么回事IO口设置代码
void Init_Dev(void)
{
//Rtc_Init();
Init_key();
Init_Set();
InitLight();
InitAUX();
InitFan();
InitDefrost();
InitComp();
BuzzInit();
GN1621_Dev_Init();
DS1302_IO_Init();
Ds1302_Init();
InitDoor();
uart_init2(9600);
uart_init1(9600);
HotKey_Dispy_Init();
uart_init3(9600);
Adc_Init();
SwitchInit();
CodeText();
TIM3_Mode_Config();
InitAlarm();
}
TIM3_Mode_Config();
//配置成PWM输出
void TIM3_Mode_Config(void)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//初始化TIM2的时间基数单位
TIM_OCInitTypeDefTIM_OCInitStructure;//初始化TIM2的外设
GPIO_InitTypeDef GPIO_InitStructure;
/*
关掉JTAD调式 PA15作为普通IO口
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//由于PA6是复用的所以要设置一下
//GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
//配置PA16 PWM输出的模式
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//打开TIM3的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//TIM2的时间基数单位设置(如计数终止值:999,从0开始 ;计数方式:向上计数)
#if INSIDE_RCC
TIM_TimeBaseStructure.TIM_Prescaler= (2 - 1); //时钟预分频数,时钟频率=64MHZ/(时钟预分频+1) 之后是8M
TIM_TimeBaseStructure.TIM_Period=3200-1; //自动重装载寄存器的值/10KHZ
#else
TIM_TimeBaseStructure.TIM_Prescaler= (9 - 1); //时钟预分频数,时钟频率=72MHZ/(时钟预分频+1) 之后是8M
TIM_TimeBaseStructure.TIM_Period=1000-1; //自动重装载寄存器的值/ 8KHZ
#endif
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//TIM3的外设的设置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//这个暂时不知道,stm32固件库里没有搜到。应该是定时器输出声明使能的意思
TIM_OCInitStructure.TIM_Pulse = 500;//设置了待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //TIM输出比较极性高
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能或者失能TIMx在CCR1上的预装载寄存器
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIM2重载寄存器ARR
TIM_ClearFlag(TIM3, TIM_FLAG_Update); //清除溢出中断标志
TIM_Cmd(TIM3, ENABLE);//使能TIM2
}
InitAlarm();的代码这不是AD IO端口
void InitAlarm(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/*
关掉JTAD调式 PA15作为普通IO口
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB,GPIO_Pin_9);
}
当写完flash后AD值就不对了
测试发现
把void InitAlarm(void)里面的
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
删除就对了AD的值又对了
或者把
TIM3_Mode_Config();
InitAlarm();
顺序变了就行了AD的值又对了
或者调试的时候停止然后在重新运行AD值也对
我想应该不是和AD的函数的问题
这是AD的代码
void ADC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure; // 优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 配置中断优先级
NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
//ADC1配置
//独立工作模式
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
//扫描方式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //不扫描
//连续转换
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换
//外部触发禁止
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
//数据右对齐
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
//用于转换的通道数
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
//规则模式通道配置
//ADC_RegularChannelConfig(ADC1, ADC_Channel_10 , 1, ADC_SampleTime_239Cycles5); //扭蛋机的
//ADC_RegularChannelConfig(ADC1, ADC_Channel_13 , 2, ADC_SampleTime_239Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_12 , 3, ADC_SampleTime_239Cycles5);
//ADC_RegularChannelConfig(ADC1, ADC_Channel_11 , 4, ADC_SampleTime_239Cycles5);
//使能ADC1的DMA
//ADC_DMACmd(ADC1, ENABLE);
ADC_NVIC_Config();
// ADC1 转换结束产生中断,在中断服务程序中读取转换值
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
//使能ADC1
ADC_Cmd(ADC1, ENABLE);
//使能ADC1复位校准寄存器
ADC_ResetCalibration(ADC1);
//检查校准寄存器是否复位完毕
while(ADC_GetResetCalibrationStatus(ADC1));
//开始校准
ADC_StartCalibration(ADC1);
//检测是否校准完毕
while(ADC_GetCalibrationStatus(ADC1));
//开启ADC1的软件转换
//ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void ADC1_2_IRQHandler(void)
{
if (ADC_GetITStatus(ADC1,ADC_IT_EOC)==SET)
{ // 读取ADC的转换值
ADC_Data = ADC_GetConversionValue(ADC1);
ADC_FinshFlag=1;
}
ADC_ClearITPendingBit(ADC1,ADC_IT_EOC);
}
void SwitchInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/*
关掉JTAD调式 PA15作为普通IO口
*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_ResetBits(GPIOC,GPIO_Pin_4);
}
//选择转换通道
void SiwtchChanl(u8 num)
{
switch(num)
{
case 0:
GPIO_ResetBits(GPIOC,GPIO_Pin_5);
GPIO_SetBits(GPIOB,GPIO_Pin_0);
break;
case 1:
GPIO_SetBits(GPIOC,GPIO_Pin_5);
GPIO_SetBits(GPIOB,GPIO_Pin_0);
break;
case 2:
GPIO_SetBits(GPIOC,GPIO_Pin_5);
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
break;
case 3:
GPIO_ResetBits(GPIOC,GPIO_Pin_5);
GPIO_ResetBits(GPIOB,GPIO_Pin_0);
break;
default:break;
}
}
//开始转换
void StartADC(u8 num)
{
u8 tmp;
CompRum.tPb=0;
//SetDisplay.Lod=0;
//SetDisplay.rES=1;
tmp=CompRum.tPb;
if(tmp>0)
{
//PT1000
ADC_RegularChannelConfig(ADC1, ADC_Channel_1 , 1, ADC_SampleTime_239Cycles5);
GPIO_SetBits(GPIOC,GPIO_Pin_4);
SiwtchChanl(num);
os_dly_wait(100);
}else
{
//NTC
ADC_RegularChannelConfig(ADC1, ADC_Channel_0 , 1, ADC_SampleTime_239Cycles5);
GPIO_ResetBits(GPIOC,GPIO_Pin_4);
SiwtchChanl(num);
os_dly_wait(20);
}
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}
u16 GetADCData(void)
{
u16 dataRe=0;
dataRe=ADC_Data;
return dataRe;
}
这是flash读写的代码#include "stmflash.h"
//#include "delay.h"
//#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK miniSTM32开发板
//STM32 FLASH 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/13
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//读取指定地址的半字(16位数据)
//faddr:读地址(此地址必须为2的倍数!!)
//返回值:对应数据.
u16 STMFLASH_ReadHalfWord(u32 faddr)
{
return *(vu16*)faddr;
}
#if STM32_FLASH_WREN //如果使能了写
//不检查的写入
//WriteAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数
void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{
u16 i;
for(i=0;i<NumToWrite;i++)
{
FLASH_ProgramHalfWord(WriteAddr,pBuffer);
WriteAddr+=2;//地址增加2.
}
}
//从指定地址开始写入指定长度的数据
//WriteAddr:起始地址(此地址必须为2的倍数!!)
//pBuffer:数据指针
//NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
#if STM32_FLASH_SIZE<256
#define STM_SECTOR_SIZE 1024 //字节
#else
#define STM_SECTOR_SIZE 2048
#endif
u16 STMFLASH_BUF;//最多是2K字节
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{
u32 secpos; //扇区地址
u16 secoff; //扇区内偏移地址(16位字计算)
u16 secremain; //扇区内剩余地址(16位字计算)
u16 i;
u32 offaddr; //去掉0X08000000后的地址
if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
FLASH_Unlock(); //解锁
offaddr=WriteAddr-STM32_FLASH_BASE; //实际偏移地址.
secpos=offaddr/STM_SECTOR_SIZE; //扇区地址0~127 for STM32F103RBT6
secoff=(offaddr%STM_SECTOR_SIZE)/2; //在扇区内的偏移(2个字节为基本单位.)
secremain=STM_SECTOR_SIZE/2-secoff; //扇区剩余空间大小
if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
while(1)
{
STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
for(i=0;i<secremain;i++)//校验数据
{
if(STMFLASH_BUF!=0XFFFF)break;//需要擦除
}
if(i<secremain)//需要擦除
{
FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除这个扇区
for(i=0;i<secremain;i++)//复制
{
STMFLASH_BUF=pBuffer;
}
STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区
}else STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.
if(NumToWrite==secremain)break;//写入结束了
else//写入未结束
{
secpos++; //扇区地址增1
secoff=0; //偏移位置为0
pBuffer+=secremain; //指针偏移
WriteAddr+=secremain; //写地址偏移
NumToWrite-=secremain; //字节(16位)数递减
if(NumToWrite>(STM_SECTOR_SIZE/2))secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
else secremain=NumToWrite;//下一个扇区可以写完了
}
};
FLASH_Lock();//上锁
}
#endif
//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数
void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
{
u16 i;
for(i=0;i<NumToRead;i++)
{
pBuffer=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
ReadAddr+=2;//偏移2个字节.
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//WriteAddr:起始地址
//WriteData:要写入的数据
void Test_Write(u32 WriteAddr,u16 WriteData)
{
STMFLASH_Write(WriteAddr,&WriteData,1);//写入一个字
}
void Erase_Flash(uint32_t WriteAddr)
{
FLASH_Unlock();
FLASH_ErasePage(WriteAddr);
FLASH_Lock();//上锁
}
这是调用flash读写函数
#include "keep.h"
#define ONE_PAGE 1024
#defineSET_BASE_ADDR STM32_FLASH_BASE+ONE_PAGE*61//第61页
#defineCompRum_ADDR SET_BASE_ADDR+100*0
#defineSetProbe_ADDR SET_BASE_ADDR+100*1
#defineSetDisplay_ADDR SET_BASE_ADDR+100*2
#defineFrost_Set_ADDR SET_BASE_ADDR+100*3
#defineFan_ADDR SET_BASE_ADDR+100*4
#defineDoor_ADDR SET_BASE_ADDR+100*5
#defineAux_s_ADDR SET_BASE_ADDR+100*6
#defineAlarm_s_ADDR SET_BASE_ADDR+100*7
#defineRTC_s_ADDR SET_BASE_ADDR+100*8
//新机第一次上电的时候清除数据
#define UPDATAFLAG 0x5887
void CreanZore(void)
{
ReadSetData();
if(PowerUp!=UPDATAFLAG)
{
PowerUp=UPDATAFLAG;
DefalutSys();
WriteSetData();
SetTime.update=1;
}
}
void ReadSetData(void)
{
u32 address;
u16 buf;
memset(buf,0,100);
address=CompRum_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&PowerUp,buf,4);
memcpy(&CompRum,&buf,sizeof(CompRum));
memset(buf,0,100);
address=SetProbe_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&SetProbe,buf,sizeof(SetProbe));
memset(buf,0,100);
address=SetDisplay_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&SetDisplay,buf,sizeof(SetDisplay));
memset(buf,0,100);
address=Frost_Set_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&Frost_Set,buf,sizeof(Frost_Set));
memset(buf,0,100);
address=Fan_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&Fan,buf,sizeof(Fan));
memset(buf,0,100);
address=Door_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&Door_s,buf,sizeof(Door_s));
memset(buf,0,100);
address=Aux_s_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&Aux_s,buf,sizeof(Aux_s));
memset(buf,0,100);
address=Alarm_s_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&Alarm_s,buf,sizeof(Alarm_s));
memset(buf,0,100);
address=RTC_s_ADDR;
STMFLASH_Read(address,buf,50);
memcpy(&Rtc_Set,buf,sizeof(Rtc_Set));
}
void WriteSetData(void)
{
u32 address;
u16 buf;
memset(buf,0,100);
address=CompRum_ADDR;
memcpy(buf,&PowerUp,4);
memcpy(&buf,&CompRum,sizeof(CompRum));
STMFLASH_Write(address,buf,50);
memset(buf,0,100);
address=SetProbe_ADDR;
memcpy(buf,&SetProbe,sizeof(SetProbe));
STMFLASH_Write(address,buf,50);
memset(buf,0,100);
address=SetDisplay_ADDR;
memcpy(buf,&SetDisplay,sizeof(SetDisplay));
STMFLASH_Write(address,buf,50);
memset(buf,0,100);
address=Frost_Set_ADDR;
memcpy(buf,&Frost_Set,sizeof(Frost_Set));
STMFLASH_Write(address,buf,50);
memset(buf,0,100);
address=Fan_ADDR;
memcpy(buf,&Fan,sizeof(Fan));
STMFLASH_Write(address,buf,50);
memset(buf,0,100);
address=Door_ADDR;
memcpy(buf,&Door_s,sizeof(Door_s));
STMFLASH_Write(address,buf,50);
memset(buf,0,100);
address=Aux_s_ADDR;
memcpy(buf,&Aux_s,sizeof(Aux_s));
STMFLASH_Write(address,buf,50);
memset(buf,0,100);
address=Alarm_s_ADDR;
memcpy(buf,&Alarm_s,sizeof(Alarm_s));
STMFLASH_Write(address,buf,50);
memset(buf,0,100);
address=RTC_s_ADDR;
memcpy(buf,&Rtc_Set,sizeof(Rtc_Set));
STMFLASH_Write(address,buf,50);
}
void UapdateProc(void)
{
if(UpdateFlag>0)
{
UpdateFlag=0;
WriteSetData();
Buzzer_Cnt=3;
}
}
#include "keep.h"
Flash读写函数#include "stmflash.h"
/
#include "stmflash.h"
系统延时发多了
自己给自己顶 :(:'(:Q:Q:Q:Q:Q:Q 试试对比一下前后AD相关的配置寄存器内容是否有变化,包括时钟配置,IO配置的内容。如有变化可以顺着线索找找哪里逻辑需要补充:)
页:
[1]
2