uc8 Seg7[17] = { 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0x00};
使用代码如下:
(需记忆,是固定的)
void SEG_DisplayValue(u8 Bit1, u8 Bit2, u8 Bit3)//参数表示想让三个数码管显示的十六进制数
{
u8 i = 0; //做循环使用
u8 code_tmp = 0;//标识数码管点亮时对应的十六进制数
code_tmp = Seg7[Bit3];//设置第三个译码管
for(i=0;i<8;i++){
//注意,这里使用的是串行输入SER,即每次只输入一位数据,也就是把8位二进制的首位给输入到数码管当中,因此,需要连续输入8次
//这里的输入指从PC机写入的数据输入到开发板
if(code_tmp & 0x80 ){//0x80二进制为1000 0000,即每次循环将code_tmp的首位与1作逻辑与
//
GPIO_SetBits(GPIOA,GPIO_Pin_1);//SER_H;如果code_tmp首位为1,那么,串行输入的SER_H值置为1
}else{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);//SER_L;//如果code_tmp首位为0,那么,串行输入的SER_H值置为0
}
GPIO_SetBits(GPIOA,GPIO_Pin_3);//SCK_H;//移位寄存器打开
code_tmp = code_tmp << 1; //让code_tmp 左移一位,准备判断下一位的串行输入的数据
//每次左移一位,即将下一位串行输出的数据放到首位
GPIO_ResetBits(GPIOA,GPIO_Pin_3);//SCK_L;//移位后,重新把移位寄存器关闭,防止出现错误
}
//其他数码管的操作同上
code_tmp = Seg7[Bit2];//设置第二个译码管
for(i=0;i<8;i++){
if(code_tmp & 0x80){
GPIO_SetBits(GPIOA,GPIO_Pin_1);//SER_H;
}else{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);//SER_L;
}
GPIO_SetBits(GPIOA,GPIO_Pin_3);//SCK_H;
code_tmp = code_tmp << 1;
GPIO_ResetBits(GPIOA,GPIO_Pin_3);//SCK_L;
}
code_tmp = Seg7[Bit1];//设置第一个译码管
for(i=0;i<8;i++){
if(code_tmp & 0x80){
GPIO_SetBits(GPIOA,GPIO_Pin_1);//SER_H;
}else{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);//SER_L;
}
GPIO_SetBits(GPIOA,GPIO_Pin_3);//SCK_H;
code_tmp = code_tmp << 1;
GPIO_ResetBits(GPIOA,GPIO_Pin_3);//SCK_L;
}
//负责输出数据的锁存,连续将输出时钟锁存打开、关闭,以保证数据不会受到其他程序段的影响
//当三个数码管的数据都已经输入完成,那么把数据锁存起来
GPIO_SetBits(GPIOA,GPIO_Pin_2);//RCLK_H;
GPIO_ResetBits(GPIOA,GPIO_Pin_2);//RCLK_L;
}
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //配置ADC时钟(只有这一个需要去"stm32f10x_rcc.h"里面找)
ADC_Cmd(ADC1,ENABLE);//打开ADC
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE); //中断配置
ADC_ResetCalibration(ADC1);//校准ADC
ADC_StartCalibration(ADC1);//校准ADC
while(ADC_GetCalibrationStatus(ADC1));//等待ADC校准完毕
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发
ADC_RegularChannelConfig(ADC1,ADC_Channel_5,1,ADC_SampleTime_13Cycles5);//规则通道配置
u8 Scan_Btn(void)
{
u16 btn_tmp = 0;
//btn_tmp 通过中断方式读取ADC的值
//S1~S8按键按下后会分别产生不同的电阻分压值,通过ADC显示,其电压值大致分为14份,按下不同的键,会产生不同的电压值,每次读取到的值不一定完全相同,但一定在对应的区间当中
if(btn_tmp < 0x0FFF/14){
return 1;//按下按键S1
}else if((btn_tmp > 0x0FFF/14) && (btn_tmp < 0x0FFF/14*3)){
return 2;//按下按键S2
}else if((btn_tmp > 0x0FFF/14*3) && (btn_tmp < 0x0FFF/14*5)){
return 3;//按下按键S3
}else if((btn_tmp > 0x0FFF/14*5) && (btn_tmp < 0x0FFF/14*7)){
return 4;//按下按键S4
}else if((btn_tmp > 0x0FFF/14*7) && (btn_tmp < 0x0FFF/14*9)){
return 5;//按下按键S5
}else if((btn_tmp > 0x0FFF/14*9) && (btn_tmp < 0x0FFF/14*11)){
return 6;//按下按键S6
}else if((btn_tmp > 0x0FFF/14*11) && (btn_tmp < 0x0FFF/14*13)){
return 7;//按下按键S7
}else if((btn_tmp > 0x0FFF/14*13) && (btn_tmp < 0x0FDF)){
return 8;//按下按键S8
}
else{
return 0; //error status & no key
}
}
s16 ds18b20_read(void)//返回值为16位数据
{
u8 val1,val2;
s16 x = 0;
ow_reset();
ow_byte_wr(OW_SKIP_ROM);
ow_byte_wr(DS18B20_CONVERT);
delay_us(750000);
ow_reset();
ow_byte_wr( OW_SKIP_ROM );
ow_byte_wr ( DS18B20_READ );
val1 = ow_byte_rd();//先读取低8位的温度值
val2 = ow_byte_rd();//再读取高8位的温度值
x = (val2<<8)+val1;//整合成16位的温度值
return x;
}
unsigned int dht11_read(void);
//返回一个32位的数据,数据格式为:
//8位湿度整数+8位湿度小数+8位温度整数+8位温度小数
int DHT=dht11_read();
DHT>>24;//湿度的整数部分
(DHT>>8)&0xff//温度的整数部分
//因此在显示湿度时,应该右移24位,温度应该右移8位,同时忽略前16位
#define I2C_PORT GPIOB
#define SDA_Pin GPIO_Pin_7
#define SCL_Pin GPIO_Pin_6
改为
#define I2C_PORT GPIOA
#define SDA_Pin GPIO_Pin_5
#define SCL_Pin GPIO_Pin_4
如果要同时使用EEPROM,则把这俩个文档名字改一下即可uint8_t LIS302DL_Read(uint8_t adds)
{
uint8_t data;
I2CStart();
I2CSendByte(0x38);
I2CWaitAck();
I2CSendByte(adds);
I2CWaitAck();
I2CStart();
I2CSendByte(0x39);
I2CWaitAck();
data=I2CReceiveByte();
I2CWaitAck();
I2CStop();
return data;
}
void LIS302DL_Write(uint8_t adds,uint8_t data)
{
I2CStart();
I2CSendByte(0x38);
I2CWaitAck();
I2CSendByte(adds);
I2CWaitAck();
I2CSendByte(data);
I2CWaitAck();
I2CStop();
}
//可以发现,LIS302DL的接受和发送函数和EEPROM的完全相同,区别只是器件的读写地址发生了变化。
//将0xa0、0xa1的读写EEPROM地址改为0x38、0x39的读写LIS302DL地址
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3) == Bit_RESET){//GPIO_ReadInputDataBit:读取引脚输入电平
LCD_DisplayStringLine(Line7, (u8*)" DO:High ");//低电平表示亮度达到阙值
}else{
LCD_DisplayStringLine(Line7, (u8*)" DO:Low ");
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //配置ADC时钟(只有这一个需要去"stm32f10x_rcc.h"里面找)
ADC_Cmd(ADC1,ENABLE);//打开ADC
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE); //中断配置
ADC_ResetCalibration(ADC1);//校准ADC
ADC_StartCalibration(ADC1);//校准ADC
while(ADC_GetCalibrationStatus(ADC1));//等待ADC校准完毕
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发
ADC_RegularChannelConfig(ADC1,ADC_Channel_5,1,ADC_SampleTime_13Cycles5);//规则通道配置
盖帽PA4—AO1,PA5—AO2
俩个ADC对应电位器RP5、RP6
初始化:GPIO模式:PA4、PA5 :GPIO_Mode_AIN(模拟输入)、
ADC(ADC1_IN4、ADC1_IN5,查看芯片手册,可以发现,PA4对应的是ADC1的通道4;PA5对应的是ADC1的通道5)
时钟:GPIOA、ADC1
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult;//因为是同时使用俩个ADC,不能在配置为独立模式;
ADC_InitStructure.ADC_NbrOfChannel = 2;//使用规则通道的数量为2个
//RegSimult:同步规则模式
NVIC:配置优先级
时钟:GPIOA、ADC1
其他函数调用
RCC_ADCCLKConfig(RCC_PCLK2_Div8); //配置ADC时钟(只有这一个需要去"stm32f10x_rcc.h"里面找)
ADC_Cmd(ADC1,ENABLE);//打开ADC
ADC_ITConfig(ADC1,ADC_IT_EOC,ENABLE); //中断配置
ADC_ResetCalibration(ADC1);//校准ADC
ADC_StartCalibration(ADC1);//校准ADC
while(ADC_GetCalibrationStatus(ADC1));//等待ADC校准完毕
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_239Cycles5);//规则通道配置
读取ADC值
u16 Get_ADCs(u8 channel)//可以使用中断方式
{
//因为ADC1同时使用俩个通道读取,因此,每次读取ADC的值,都要选择要读取的通道
u16 ADC_Val = 0;
ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5); //这一句是重点
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
ADC_Val = ADC_GetConversionValue(ADC1);
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
return ADC_Val;
}
在这里插入代码片
其他函数调用
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);//选择输入触发源:TI2:表示通道2,PF2:经过滤波器后将接到捕捉比较通道IC2;
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);//选择从模式 上升沿重新初始化计数器,并且产生一个更新寄存器的信号
TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);//配置从模式
TIM_Cmd(TIM3, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
中断函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3, TIM_IT_CC2) == SET){
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
IC2Value = TIM_GetCapture2(TIM3);
if (IC2Value != 0){
DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;//占空比,
Frequency = SystemCoreClock / IC2Value;//频率,单位:HZ
}else{
DutyCycle = 0;
Frequency = 0;
}
}
}