STM8S个模块初始化.docx
《STM8S个模块初始化.docx》由会员分享,可在线阅读,更多相关《STM8S个模块初始化.docx(7页珍藏版)》请在冰豆网上搜索。
STM8S个模块初始化
STM8S各个模块初始化{转}原作者真不错
2012-12-0922:
20:
38|分类:
默认分类|标签:
stm8s|举报|字号订阅
/***************可选择的内部或者外部时钟*******************/
#ifdefHSE_EXT
voidClkInit(void)
{
CLK_ICKR=0X00;//禁止高速内部时钟,从停机(Halt)或活跃停机(ActiveHalt)模式快速唤醒禁止
CLK_ECKR|=0X01;//使能外部时钟
while(!
(CLK_ECKR&0x02));
//看外部晶振是否启动
CLK_CKDIVR=0Xf9;//外部12MHZ晶振作为CPU时钟
//入选24Mhz就在CLK_SWCR|=0X02;出现问题
CLK_SWR=0XB4;//主时钟选择为外部晶振
(CLK_SWCR&0x8));
CLK_SWCR|=0X02;//时钟切换
CLK_PCKENR1=0Xaf;//使能fMASTER时钟与对应外设的连接(仅I2C和TIM2,andTIM1)还有UART1,uart3spi
CLK_PCKENR2=0X00;//0X0C;
CLK_CSSR=0X00;//时钟安全系统寄存器关
while((CLK_CCOR&0x04));//空闲才可以写CCOSEL
CLK_CCOR|=0X0d;//使能CCO始终输出,6M
(CLK_CCOR&0x04));//看CCO输出的时钟是否正在工作
while((CLK_CCOR&0x02));//等待可输出时钟可用
//CLK_HSITRIMR=0X00-1;//HSI时钟修正寄存器,HSITRIM[3:
0]:
HSI修正值
}
#else
CLK_ICKR=0X01;//时能高速内部时钟,从停机(Halt)或活跃停机(ActiveHalt)模式快速唤醒使能
CLK_ECKR=0X00;//禁止外部时钟
CLK_SWR=0XE1;//选择16M内部时钟为主时钟
CLK_SWCR=0X00;//禁止时钟切换
CLK_CKDIVR=0X08;//8MHZ[4:
3]01:
fHSI=fHSIRC输出/2,[2:
0]000:
fCPU=fMASTER
CLK_HSITRIMR=0X00-1;//HSI时钟修正寄存器,HSITRIM[3:
#endif
/********外部中断****************/
voidInterruptInit(void)
PD_DDR&=~(0X40);//PD6设置为按键输?
PD_CR1|=0X40;
PD_CR2&=~(0X40);//禁止外部中断
//PD_CR2|=0X40;//使能外部中断
EXTI_CR1|=0X80;//PD6下降沿出触发中断
//EXTI_CR1|=0X40;//PD6上升沿出触发中断
/*****************串口收发******************/
voidUart3Init(void)
UART3_CR1=0x00;
UART3_CR2=0x00;
UART3_CR3=0x00;//1个停止位
UART3_BRR2=0x04;//24M的Fmaster下9600的波特率
UART3_BRR1=0x9c;//24000000/9600=0x09c4
UART3_CR2=0x2c;//发送接收都使能,使能接收中断
voidUart3SendChar(U8*Send_Buff,U8Cnt)
U8i;
for(i=0;i{while(!(UART3_SR&0x80));UART3_DR=Send_Buff[i];}}/***********定时器**************************/voidTimer1Init(void){TIM1_CR1|=0X04;//自动重载,只有溢出才产生更新中断TIM1_IER|=0X01;//允许更新中断//TIM2_SR1=0X00;//状态寄存器TIM1_PSCR=0X01;//PSC[3:0]:预分频器的值,开预分频功能不许使能EGR中的UG位//TIM1_PSCR=0X00;//PSC[3:0]:4预分频器的值TIM2_EGR|=0X01;//时间产生状态寄存器,重新初始化计数器,并产生一个更新事件。//如果不开预分频功能,此位可以删去//TIM2_CCMR1=0X00;//捕获/比较模式寄存器,可用于选择PWM输出端口//TIM2_CCMR1=0X68;//PWM模式,通道1,预装载使能//TIM2_CCMR2=0X68;//PWM模式,通道2,预装载使能//TIM2_CCER2=0X03;//使能PWM输出通道//TIM2_CCER1=0X03;//使能PWM输出通道TIM1_CNTRH=0X9C;//计数值TIM1_CNTRL=0X40;TIM1_ARRH=0X9C;//自动重载值(10ms进一次中断),8M2分频,40000/4000000=10msTIM1_ARRL=0X40;TIM1_CR1|=0X01;//开计数器}/************AWU唤醒********************/voidAWU_Open(void){AWU_APR=0X3E;//APPRdiV=64AWU_TBR=0X0D;//timeinterval=2^11*APPRdiV/Fls=2048*64/128KHZ=1S0D=2S//AWU_TBR=0X0E;//timeinterval=2^11*APPRdiV/Fls=2048*64/128KHZ=1S0E==大约5SAWU_CSR=0x30;//enableAWU,AWU_INTCLK_ICKR|=0X20;//1:活跃停机(ActiveHalt)模式下主dianyatiaojieqiguanbi}voidAWU_Close(void){AWU_APR=0X3F;//APPRdiVAWU_TBR=0X00;//disabletimeintervalAWU_CSR=0x00;//disableAWUCLK_ICKR&=~(0X20);}voidEEPROM_Init(void){FLASH_CR1=0x00;FLASH_CR2=0x00;FLASH_DUKR=MASS_KEY1;FLASH_DUKR=MASS_KEY2;//密钥使能while(!(FLASH_IAPSR&0x08));/*等待写保护解锁*/}/***********EEPROM***************************/u8EEPROM_Write(u8addr,u8dat){u16TimeOut;*((u8*)(addr+EEP_BASE))=dat;for(TimeOut=0;TimeOut<0xFFFF;TimeOut++){if(FLASH_IAPSR&(WR_PG_DIS|EOP_BIT))return1;//编程完成或者写到了写保护区}return0;//超时退出//while(!(FLASH_IAPSR&0x02));/*等待写完成*/}u8EEPROM_Read(u8addr){return*((u8*)(EEP_BASE+addr));}voidEEPROM_THREE_BYTE_WRITE(void){EEPROM_Write(0x00,i2c_buff[0]);EEPROM_Write(0x01,i2c_buff[1]);EEPROM_Write(0x02,i2c_buff[2]);}voidEEPROM_THREE_BYTE_READ(void){if(ADC_OnOff==1)ADC_ON_OR_OFF=2;elseADC_ON_OR_OFF=EEPROM_Read(0x00);ADC_OPEN_MIN=EEPROM_Read(0x01);ADC_OPEN_TIME=EEPROM_Read(0x02);}/**************ADC***********************/voidadc_init(void){ADC_CR1|=0X00;//关闭ADC,2分频ADC_CR2|=0X08;//数据右对齐,low8BITATADC_DRL;非扫描模式ADC_CSR=0X04;//选择通道4,禁止中断}/********取走ADC转换yi个通道的数据**********/u16adc_converter(void){u8m;for(m=0;m<30;m++);//等待上电完成ADC_CR1|=0X1;//启动转换while(!(ADC_CSR&0x80));//等待转换结束14个时钟周期ADC_CSR&=0X7F;//清除中断标志returnADC_DR;}/****************I2C**************************/voidI2C_init(void){I2C_CCRH=0x00;//标准I2C接口//I2C_CCRL=80;//I2C_FREQR=0x10;//输入外设时钟频率为2MHzI2C_CR1=0x00;//禁止I2C外设I2C_FREQR=8;//8MHZ//经测试主芯片时钟至少》8Mhz才能正常收到数据I2C_OARL=SLAVE_ADDRESS;//I2C_OARH=0x40;//七位//I2C_OARH=0xC0|((SLAVE_ADDRESS&0x300)>>7);//十位I2C_CR1=0x01;//开I2CI2C_CR2|=0x04;//只产生应答信号,不产生起始和停止位I2C_ITR=0x07;//使能中断}voidspi_init(void){SPI_CR2=0X01;SPI_CR1=0X44;//8MHZ主模式PB_DDR|=1<<5;//SCKPB_CR1|=1<<5;//outputPB_DDR|=1<<6;//MOSIPB_CR1|=1<<6;//outputPB_DDR&=~(1<<7);//MISOPB_CR1|=1<<7;//inputwithpull-upCLK_PCKENR1|=0x10;SPI1_CR1=0x04;SPI1_CR2=0x03;SPI1_CRCPR=0x07;SPI1_ICR=0x00;SPI1_CR1|=0x40;}/*************SPI**************************/UINT8SPI_RW(UINT8byte){unsignedchardata;//while(SPI1_SR&0x80);//Busyflagwhile(!SPI1_SR&0x02);SPI1_DR=byte;while(!SPI1_SR&0x01);_asm("nop");_asm("nop");_asm("nop");_asm("nop");data=SPI1_DR;return(data);}/****************按键*************************/externu16keyvalue;u8f_keytime;//externu8KeyRestFlag;u16u16Timer1Cnt;voidkeyscan(void){staticu16f_key_state=0;u8key_up_flag=0;staticu16keyoldbuf=0;staticu16keyinbuf=0,keychkbuf=0,keycvtbuf=0;if(f_keytime==1){f_keytime=0;key_up_flag=PC_IDR&0x10;if(key_up_flag==0x00)//{if(u16Timer1Cnt>=KeyInContinue1S){//KeyRestFlag=0;u16Timer1Cnt=0;keyinbuf=KeyRst;}}else{//KeyRestFlag=0;keyinbuf=0;u16Timer1Cnt=0;}if(keyinbuf==keychkbuf){if(f_key_state){keycvtbuf=keychkbuf;f_key_state=0;}}else{keychkbuf=keyinbuf;f_key_state=1;}}if(keycvtbuf!=keyoldbuf){keyvalue=keycvtbuf&(~keyoldbuf);keyoldbuf=keycvtbuf;}/*****if(keycvtbuf!=keyoldbuf)//按键按下{//keyvalue|=keycvtbuf&(~keyoldbuf);keymediavalue=keycvtbuf&(~keyoldbuf);//keyoldbuf=keycvtbuf;key_up_flag=1;//returnkeyvalue;}if(key_up_flag==1)//按键抬起if(keycvtbuf==keyoldbuf){key_up_flag=0;keyvalue=keymediavalue;}}//return0;****/}
(UART3_SR&0x80));
UART3_DR=Send_Buff[i];
/***********定时器**************************/
voidTimer1Init(void)
TIM1_CR1|=0X04;//自动重载,只有溢出才产生更新中断
TIM1_IER|=0X01;//允许更新中断
//TIM2_SR1=0X00;//状态寄存器
TIM1_PSCR=0X01;//PSC[3:
预分频器的值,开预分频功能不许使能EGR中的UG位
//TIM1_PSCR=0X00;//PSC[3:
4预分频器的值
TIM2_EGR|=0X01;//时间产生状态寄存器,重新初始化计数器,并产生一个更新事件。
//如果不开预分频功能,此位可以删去
//TIM2_CCMR1=0X00;//捕获/比较模式寄存器,可用于选择PWM输出端口
//TIM2_CCMR1=0X68;//PWM模式,通道1,预装载使能
//TIM2_CCMR2=0X68;//PWM模式,通道2,预装载使能
//TIM2_CCER2=0X03;//使能PWM输出通道
//TIM2_CCER1=0X03;//使能PWM输出通道
TIM1_CNTRH=0X9C;//计数值
TIM1_CNTRL=0X40;
TIM1_ARRH=0X9C;//自动重载值(10ms进一次中断),8M2分频,40000/4000000=10ms
TIM1_ARRL=0X40;
TIM1_CR1|=0X01;//开计数器
/************AWU唤醒********************/
voidAWU_Open(void)
AWU_APR=0X3E;//APPRdiV=64
AWU_TBR=0X0D;//timeinterval=2^11*APPRdiV/Fls=2048*64/128KHZ=1S0D=2S
//AWU_TBR=0X0E;//timeinterval=2^11*APPRdiV/Fls=2048*64/128KHZ=1S0E==大约5S
AWU_CSR=0x30;//enableAWU,AWU_INT
CLK_ICKR|=0X20;//1:
活跃停机(ActiveHalt)模式下主dianyatiaojieqiguanbi
voidAWU_Close(void)
AWU_APR=0X3F;//APPRdiV
AWU_TBR=0X00;//disabletimeinterval
AWU_CSR=0x00;//disableAWU
CLK_ICKR&=~(0X20);
voidEEPROM_Init(void)
FLASH_CR1=0x00;
FLASH_CR2=0x00;
FLASH_DUKR=MASS_KEY1;
FLASH_DUKR=MASS_KEY2;//密钥使能
(FLASH_IAPSR&0x08));/*等待写保护解锁*/
/***********EEPROM***************************/
u8EEPROM_Write(u8addr,u8dat)
u16TimeOut;
*((u8*)(addr+EEP_BASE))=dat;
for(TimeOut=0;TimeOut<0xFFFF;TimeOut++)
if(FLASH_IAPSR&(WR_PG_DIS|EOP_BIT))return1;//编程完成或者写到了写保护区
return0;
//超时退出
//while(!
(FLASH_IAPSR&0x02));/*等待写完成*/
u8EEPROM_Read(u8addr)
return*((u8*)(EEP_BASE+addr));
voidEEPROM_THREE_BYTE_WRITE(void)
EEPROM_Write(0x00,i2c_buff[0]);
EEPROM_Write(0x01,i2c_buff[1]);
EEPROM_Write(0x02,i2c_buff[2]);
voidEEPROM_THREE_BYTE_READ(void)
if(ADC_OnOff==1)
ADC_ON_OR_OFF=2;
else
ADC_ON_OR_OFF=EEPROM_Read(0x00);
ADC_OPEN_MIN=EEPROM_Read(0x01);
ADC_OPEN_TIME=EEPROM_Read(0x02);
/**************ADC***********************/
voidadc_init(void)
ADC_CR1|=0X00;//关闭ADC,2分频
ADC_CR2|=0X08;//数据右对齐,low8BITATADC_DRL;非扫描模式
ADC_CSR=0X04;//选择通道4,禁止中断
/********取走ADC转换yi个通道的数据**********/
u16adc_converter(void)
u8m;
for(m=0;m<30;m++);//等待上电完成
ADC_CR1|=0X1;//启动转换
(ADC_CSR&0x80));//等待转换结束14个时钟周期
ADC_CSR&=0X7F;//清除中断标志
returnADC_DR;
/****************I2C**************************/
voidI2C_init(void)
I2C_CCRH=0x00;//标准I2C接口
//I2C_CCRL=80;
//I2C_FREQR=0x10;//输入外设时钟频率为2MHz
I2C_CR1=0x00;//禁止I2C外设
I2C_FREQR=8;//8MHZ//经测试主芯片时钟至少》8Mhz才能正常收到数据
I2C_OARL=SLAVE_ADDRESS;//
I2C_OARH=0x40;//七位
//I2C_OARH=0xC0|((SLAVE_ADDRESS&0x300)>>7);//十位
I2C_CR1=0x01;//开I2C
I2C_CR2|=0x04;//只产生应答信号,不产生起始和停止位
I2C_ITR=0x07;//使能中断
voidspi_init(void)
SPI_CR2=0X01;
SPI_CR1=0X44;//8MHZ主模式
PB_DDR|=1<<5;//SCK
PB_CR1|=1<<5;//output
PB_DDR|=1<<6;//MOSI
PB_CR1|=1<<6;//output
PB_DDR&=~(1<<7);//MISO
PB_CR1|=1<<7;//inputwithpull-up
CLK_PCKENR1|=0x10;
SPI1_CR1=0x04;
SPI1_CR2=0x03;
SPI1_CRCPR=0x07;
SPI1_ICR=0x00;
SPI1_CR1|=0x40;
/*************SPI**************************/
UINT8SPI_RW(UINT8byte)
unsignedchardata;
//while(SPI1_SR&0x80);//Busyflag
SPI1_SR&0x02);
SPI1_DR=byte;
SPI1_SR&0x01);
_asm("nop");
data=SPI1_DR;
return(data);
/****************按键*************************/
externu16keyvalue;
u8f_keytime;
//externu8KeyRestFlag;
u16u16Timer1Cnt;
voidkeyscan(void)
staticu16f_key_state=0;
u8key_up_flag=0;
staticu16keyoldbuf=0;
staticu16keyinbuf=0,keychkbuf=0,keycvtbuf=0;
if(f_keytime==1)
f_keytime=0;
key_up_flag=PC_IDR&0x10;
if(key_up_flag==0x00)//
if(u16Timer1Cnt>=KeyInContinue1S)
//KeyRestFlag=0;
u16Timer1Cnt=0;
keyinbuf=KeyRst;
keyinbuf=0;
if(keyinbuf==keychkbuf)
if(f_key_state)
keycvtbuf=keychkbuf;
f_key_state=0;
keychkbuf=keyinbuf;
f_key_state=1;
if(keycvtbuf!
=keyoldbuf)
keyvalue=keycvtbuf&(~keyoldbuf);
keyoldbuf=keycvtbuf;
/*****
=keyoldbuf)//按键按下
//keyvalue|=keycvtbuf&(~keyoldbuf);
keymediavalue=keycvtbuf&(~keyoldbuf);
//keyoldbuf=keycvtbuf;
key_up_flag=1;
//returnkeyvalue;
if(key_up_flag==1)//按键抬起
if(keycvtbuf==keyoldbuf)
key_up_flag=0;
keyvalue=keymediavalue;
//return0;
****/
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1