例程是用正点原子的战舰STM32开发板
main.c文件
#include "main.h"
#include "bmp.h"
/************************************************
************************************************/
u32 Alarm_Clock_Val = 0 ;
u8 Medicine_Flag = 0; //吃药标志位
void Periph_All_Init(void);
void Set_Alarm_Clock(void);
_bool OledDisplayTimeFlag = FALSE;
_bool OledDisplayParamFlag = FALSE;
_bool OledDisplayGasFlag = FALSE;
_bool Task500MsEventFlag = TRUE;
_bool MedicineEventFlag = TRUE;
_bool HeartRateEventFlag = TRUE;
#define PHVAL_MAX 1000 //PH值报警
/* 用户区当前设备状态结构体*/
dataPoint_t currentDataPoint;
extern gizwitsProtocol_t gizwitsProtocol;
extern u8 display_status;
extern u8 Water_Temp_status;
//WIFI连接状态
//wifi_sta 0: 断开
// 1: 已连接
u8 wifi_sta=0;
//协议初始化
void Gizwits_Init(void)
{
TIM3_Int_Init(9,7199);//1MS系统定时
usart3_init(9600);//WIFI初始化
memset((uint8_t*)¤tDataPoint, 0, sizeof(dataPoint_t));//设备状态结构体初始化
gizwitsInit();//缓冲区初始化
}
int main(void)
{
u8 able[7] = {0x50,0x34,0x20,0x19,0x04,0x05,0x19};
u8 temp = 0;
u8 wifi_con=0;//记录wifi连接状态 1:连接 0:断开
u8 temperature;
u8 humidity;
Periph_All_Init();
//gizwitsSetMode(WIFI_RESET_MODE);
while(1)
{
if(Medicine_Flag == 0)
{
switch(display_status)
{
case 0:
if(OledDisplayTimeFlag == TRUE)
{
DS1302_GetTime(able);
OledDisplayTimeFlag = FALSE;
OLED_Clear_static(1, 2, 7);
FuncReg(&OledDisplayTimeFlag, 10000, TRUE);
OLED_Show_32_32(16*2-8,2,able[2] / 10 + '0');
OLED_Show_32_32(16*3-8,2,able[2] % 10 + '0');
OLED_Show_32_32(16*4-8,2,':');
OLED_Show_32_32(16*5-8,2,able[1] / 10 + '0');
OLED_Show_32_32(16*6-8,2,able[1] % 10 + '0');
OLED_ShowChar(32, 6, able[6] / 10 + '0',16);
OLED_ShowChar(32+8*1, 6, able[6] % 10 + '0',16);
OLED_ShowChar(32+8*2, 6, '-',16);
OLED_ShowChar(32+8*3, 6, able[4] / 10 + '0',16);
OLED_ShowChar(32+8*4, 6, able[4] % 10 + '0',16);
OLED_ShowChar(32+8*5, 6, '-',16);
OLED_ShowChar(32+8*6, 6, able[3] / 10 + '0',16);
OLED_ShowChar(32+8*7, 6, able[3] % 10 + '0',16);
}
OledDisplayGasFlag = TRUE;
OledDisplayParamFlag = TRUE;
break;
case 1:
{
if(OledDisplayParamFlag == TRUE)
{
OledDisplayParamFlag = FALSE;
OLED_Clear_static(2, 2, 7);
FuncReg(&OledDisplayParamFlag, 200, TRUE);
OLED_ShowCHinese(16 * 0, 2, 12);
OLED_ShowCHinese(16 * 1, 2, 13);
OLED_ShowChar(16 * 2, 2, ':',16);
OLED_ShowCHinese(16 * 6, 2, 16);
OLED_ShowNum(16 * 3, 2, temperature, 3, 16);
OLED_ShowCHinese(16 * 0, 4, 14);
OLED_ShowCHinese(16 * 1, 4, 15);
OLED_ShowChar(16 * 2, 4, ':',16);
OLED_ShowChar(16 * 6, 4, '%',16);
OLED_ShowNum(16 * 3, 4, humidity, 3, 16);
OLED_ShowChar(8 * 0, 6, 'M',16);
OLED_ShowChar(8 * 1, 6, 'Q',16);
OLED_ShowChar(8 * 2, 6, '_',16);
OLED_ShowChar(8 * 3, 6, '1',16);
OLED_ShowChar(8 * 4, 6, ':',16);
OLED_ShowNum(16 * 3, 6, ADC_Val[0], 4, 16);
}
OledDisplayTimeFlag = TRUE;
OledDisplayGasFlag = TRUE;
}
break;
case 2:
if(OledDisplayGasFlag == TRUE)
{
OledDisplayGasFlag = FALSE;
FuncReg(&OledDisplayGasFlag, 5000, TRUE);
OLED_Clear_static(3, 2, 7);
OLED_ShowCHinese(16 * 0, 2, 30);
OLED_ShowCHinese(16 * 1, 2, 31);
OLED_ShowCHinese(16 * 2, 2, 32);
OLED_ShowCHinese(16 * 3, 2, 33);
OLED_ShowCHinese(16 * 4, 2, 34);
OLED_ShowCHinese(16 * 5, 2, 35);
OLED_ShowCHinese(16 * 6, 2, 36);
OLED_ShowCHinese(16 * 0, 4, 37);
OLED_ShowCHinese(16 * 1, 4, 38);
OLED_ShowCHinese(16 * 2, 4, 39);
OLED_ShowCHinese(16 * 3, 4, 40);
OLED_ShowCHinese(16 * 4, 4, 41);
OLED_ShowCHinese(16 * 5, 4, 42);
OLED_ShowCHinese(16 * 6, 4, 43);
OLED_ShowString(0, 6, (u8 *)" Any Key Exit..",16);
Jq_8400_Music_Num(MUSIC_GAS_WARNING);
}
break;
case 3:
{
OLED_Clear_static(5, 2, 7);
OLED_ShowCHinese(0 ,2 ,27);
OLED_ShowCHinese(16 ,2 ,28);
OLED_ShowCHinese(16 * 2 ,2 ,29);
OLED_ShowChar(16 * 3, 2, ':',16);
temp = Heart_Rate();
display_status = 4;
}
break;
case 4:
{
if((temp/100) != 0)
OLED_Show_32_32(16 * 4 - 8,3,temp/100 + '0');
OLED_Show_32_32(16 * 4 +16- 8, 3,(temp % 100)/10 + '0');
OLED_Show_32_32(16 * 4 +32- 8, 3,temp % 10 + '0');
OLED_ShowString(32-8, 6, (uint8_t *)" bpm", 16);
display_status = 5;
if(temp <= 60)
Jq_8400_Music_Num(MUSIC_HEART_REAT_LOW);
else if(temp < 110)
Jq_8400_Music_Num(MUSIC_HEART_REAT_NORMAL);
else
Jq_8400_Music_Num(MUSIC_HEART_REAT_HIGH);
}
break;
default: break;
}
}
else if(MedicineEventFlag)
{
MedicineEventFlag = FALSE;
FuncReg(&MedicineEventFlag, 5000, TRUE);
OLED_Clear_static(4, 2, 7);
OLED_ShowCHinese(18 * 0, 2, 17);
OLED_ShowCHinese(18 * 1, 2, 18);
OLED_ShowCHinese(18 * 2, 2, 19);
OLED_ShowCHinese(18 * 3, 2, 20);
OLED_ShowCHinese(18 * 4, 2, 21);
OLED_ShowCHinese(18 * 2, 4, 22);
OLED_ShowCHinese(18 * 3, 4, 23);
OLED_ShowCHinese(18 * 4, 4, 24);
OLED_ShowCHinese(18 * 5, 4, 25);
OLED_ShowCHinese(18 * 6, 4, 26);
OLED_ShowString(0, 6, (u8 *)" Any Key Exit..",16);
Jq_8400_Music_Num(MUSIC_MEDICINE);
}
if(Task500MsEventFlag == TRUE)
{
Task500MsEventFlag = FALSE;
FuncReg(&Task500MsEventFlag, 500, TRUE);
currentDataPoint.valueHum = humidity;
currentDataPoint.valueGas = ADC_Val[0];
currentDataPoint.valueHeart_Rate = temp;
if(ADC_Val[0] > PHVAL_MAX){
BUZEER_ENABLE;
display_status = 2;
}
else{
BUZEER_DISABLE;
}
currentDataPoint.valueTemp = temperature;
DHT11_Read_Data(&temperature,&humidity); //读取温湿度值
currentDataPoint.valuerssi = gizwitsProtocol.wifiStatusData.rssi;
}
if(wifi_con!=wifi_sta)
{
wifi_con=wifi_sta;
//wifi_con?printf("connect"):printf("close");
}
gizwitsHandle((dataPoint_t *)¤tDataPoint);//协议处理
// key = KEY_Scan(0);
// if(key==KEY1_PRES)//KEY1按键
// {
// printf("WIFI进入AirLink连接模式\r\n");
// gizwitsSetMode(WIFI_AIRLINK_MODE);//Air-link模式接入
// }
// if(key == KEY1_PRES)//KEY_UP按键
// {
// printf("WIFI复位,请重新配置连接\r\n");
// gizwitsSetMode(WIFI_RESET_MODE);//WIFI复位
// wifi_sta=0;//标志wifi已断开
// }
}
}
void Periph_All_Init(void)
{
delay_init(); //延时函数初始化
//KEY_Init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
Periph_Init(); //初始化与LED连接的硬件接口
Key_Io_Init();
BUZEER_DISABLE;
uart_init(115200);
usart2_init(9600);
Gizwits_Init(); //协议初始化
OLED_Init(); //初始化OLED
DHT11_Init();
Adc_Init();
OLED_Clear();
Ds1302_GpioInit();
Jq_8400_Set_Volume(20);
delay_ms(10);
Jq_8400_Music_Num(MUSIC_INIT);
//DS1302_Initial();
//DS1302_SetTime(able);
//DS1302_GetTime(able);
OLED_DrawBMP(0,0,128,1,BMP1);
OLED_ShowCHinese(18 * 1, 2, 0);
OLED_ShowCHinese(18 * 2, 2, 1);
OLED_ShowCHinese(18 * 3, 2, 2);
OLED_ShowChar(18 * 4, 2, 'N',16);
OLED_ShowChar(18 * 5 - 8, 2, 'I',16);
OLED_ShowChar(18 * 5, 2, 'I',16);
OLED_ShowChar(18 * 6 - 8, 2, 'T',16);
OLED_ShowCHinese(18 * 1, 4, 3);
OLED_ShowCHinese(18 * 2, 4, 4);
OLED_ShowCHinese(18 * 3, 4, 5);
OLED_ShowCHinese(18 * 4, 4, 6);
OLED_ShowCHinese(18 * 5, 4, 7);
OLED_ShowCHinese(18 * 6, 4, 8);
OLED_ShowChar(18 * 3, 6, '-', 16);
OLED_ShowCHinese(18 * 4, 6, 9);
OLED_ShowCHinese(18 * 5, 6, 10);
OLED_ShowCHinese(18 * 6, 6, 11);
FuncReg(&OledDisplayTimeFlag, 5000, TRUE);
}
void Set_Alarm_Clock(void)
{
static u8 previousvalueTime = 0;
if(previousvalueTime != currentDataPoint.valueTime)
{
switch(currentDataPoint.valueTime)
{
case Time_VALUE0: //未定义
Alarm_Clock_Val = 0;
//user handle
break;
case Time_VALUE1: //10S
Alarm_Clock_Val = 10;
//user handle
break;
case Time_VALUE2: //100S
Alarm_Clock_Val = 100;
//user handle
break;
case Time_VALUE3: //1000S
Alarm_Clock_Val = 1000;
//user handle
break;
case Time_VALUE4: //1分钟
//user handle
Alarm_Clock_Val = 60;
break;
case Time_VALUE5: //10分钟
//user handle
Alarm_Clock_Val = 60 * 10;
break;
case Time_VALUE6: //100分钟
//user handle
Alarm_Clock_Val = 60 * 100;
break;
case Time_VALUE7: //1小时
//user handle
Alarm_Clock_Val = 60 * 60;
break;
case Time_VALUE8: //2小时
//user handle
Alarm_Clock_Val = 60 * 60 * 2;
break;
case Time_VALUE9: //4小时
//user handle
Alarm_Clock_Val = 60 * 60 * 4;
break;
case Time_VALUE10: //12小时
//user handle
Alarm_Clock_Val = 60 * 60 * 12;
break;
case Time_VALUE11: //24小时
//user handle
Alarm_Clock_Val = 60 * 60 * 24;
break;
default:
break;
}
}
previousvalueTime = currentDataPoint.valueTime;
}
ds1203.c文件
#include "ds1302.h"
void Ds1302_GpioInit(void)
{
GPIO_InitTypeDef GPIO_InitTypeState;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeState.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitTypeState.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_13;
GPIO_InitTypeState.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitTypeState);
GPIO_InitTypeState.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitTypeState.GPIO_Pin = GPIO_Pin_14;
GPIO_Init(GPIOB, &GPIO_InitTypeState);
}
u8 DS1302_ReadByte()
{
u8 i;
u8 dat = 0;
IO_IN();
for (i=0; i<8; i++) //8位计数器
{
SCLK = 0; //时钟线拉低
delay_us(2);
dat >>= 1; //数据右移一位
if (IOIN) dat |= 0x80; //读取数据
SCLK = 1; //时钟线拉高
delay_us(2);
}
return dat;
}
/**************************************
向DS1302写1字节数据
**************************************/
void DS1302_WriteByte(u8 dat)
{
char i;
IO_OUT();
for (i=0; i<8; i++) //8位计数器
{
SCLK = 0; //时钟线拉低
delay_us(2);
IOOUT = (dat & 0X01); //送出到端口
dat >>= 1; //移出数据
SCLK = 1; //时钟线拉高
delay_us(2);
}
}
/**************************************
读DS1302某地址的的数据
**************************************/
u8 DS1302_ReadData(u8 addr)
{
u8 dat;
RST = 0;
delay_us(2);
SCLK = 0;
delay_us(2);
RST = 1;
delay_us(2);
DS1302_WriteByte(addr); //写地址
dat = DS1302_ReadByte(); //读数据
SCLK = 1;
RST = 0;
return dat;
}
/**************************************
往DS1302的某个地址写入数据
**************************************/
void DS1302_WriteData(u8 addr, u8 dat)
{
RST = 0;
delay_us(2);
SCLK = 0;
delay_us(2);
RST = 1;
delay_us(2);
DS1302_WriteByte(addr); //写地址
DS1302_WriteByte(dat); //写数据
SCLK = 1;
RST = 0;
}
/**************************************
写入初始时间
**************************************/
void DS1302_SetTime(u8 *p)
{
u8 addr = 0x80;
u8 n = 7;
DS1302_WriteData(0x8e, 0x00); //允许写操作
while (n--)
{
DS1302_WriteData(addr, *p++);
addr += 2;
}
DS1302_WriteData(0x8e, 0x80); //写保护
}
/**************************************
读取当前时间
**************************************/
void DS1302_GetTime(u8 *p)
{
u8 addr = 0x81;
u8 n = 7;
u8 temp = 0;
while (n--)
{
temp = DS1302_ReadData(addr);
*p = ((temp)>>4)*10 + ((temp)&0x0F);
p++;
addr += 2;
}
}
/**************************************
初始化DS1302
**************************************/
void DS1302_Initial()
{
RST = 0;
SCLK = 0;
DS1302_WriteData(0x8e, 0x00); //允许写操作
DS1302_WriteData(0x80, 0x00); //时钟启动
DS1302_WriteData(0x90, 0xa6); //一个二极管+4K电阻充电
DS1302_WriteData(0x8e, 0x80); //写保护
}
使用iic通信
#include "myiic.h"
#include "delay.h"
//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
IIC_SCL=1;
IIC_SDA=1;
}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}
void IIC_WriteBytes(u8 WriteAddr,u8* data,u8 dataLength)
{
u8 i;
IIC_Start();
IIC_Send_Byte(WriteAddr); //发送写命令
IIC_Wait_Ack();
for(i=0;i<dataLength;i++)
{
IIC_Send_Byte(data[i]);
IIC_Wait_Ack();
}
IIC_Stop();//产生一个停止条件
delay_ms(10);
}
void IIC_ReadBytes(u8 deviceAddr, u8 writeAddr,u8* data,u8 dataLength)
{
u8 i;
IIC_Start();
IIC_Send_Byte(deviceAddr); //发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(writeAddr);
IIC_Wait_Ack();
IIC_Send_Byte(deviceAddr|0X01);//进入接收模式
IIC_Wait_Ack();
for(i=0;i<dataLength-1;i++)
{
data[i] = IIC_Read_Byte(1);
}
data[dataLength-1] = IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
delay_ms(10);
}
void IIC_Read_One_Byte(u8 daddr,u8 addr,u8* data)
{
IIC_Start();
IIC_Send_Byte(daddr); //发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(addr);//发送地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(daddr|0X01);//进入接收模式
IIC_Wait_Ack();
*data = IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
}
void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data)
{
IIC_Start();
IIC_Send_Byte(daddr); //发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(addr);//发送地址
IIC_Wait_Ack();
IIC_Send_Byte(data); //发送字节
IIC_Wait_Ack();
IIC_Stop();//产生一个停止条件
delay_ms(10);
}
这些只是部分代码源代码放链接里了
链接:https://pan.baidu.com/s/1Cfk25AFRfZ3JWcVONCNMzw
提取码:1111