|
|
#include "stm32f10x.h"
|
|
|
#include <stdio.h>
|
|
|
#include "OV2640/dcmi_ov2640.h"
|
|
|
#include <stm32f10x.h>
|
|
|
#include "sys.h"
|
|
|
#include "adc.h"
|
|
|
#include "uartint.h"
|
|
|
extern void SysRead(void);
|
|
|
extern void SysSave(void);
|
|
|
vu8 dat11[36];
|
|
|
int len;
|
|
|
vu16 timeout = 0; // 定义倒计时,单位ms
|
|
|
vu8 timeoutoled = 0; // 定义倒计时,单位ms
|
|
|
#define beepa PAout(7) // 定义蜂鸣器的引脚,初始化成od
|
|
|
#define MQ2 PAin(7)
|
|
|
#include "ds18b20.h" //已验证
|
|
|
#include "duoji.h" //已验证
|
|
|
#include "dht11.h" //已验证
|
|
|
#include "jq8400.h" //已验证
|
|
|
#include "motor.h" //已验证
|
|
|
#include "oled.h"
|
|
|
#include "gps.h"
|
|
|
#include "chaoshengbo.h"
|
|
|
#define led PAout(8)
|
|
|
#define uartoled 2 // oled用的串口
|
|
|
|
|
|
vu8 hour = 0, min = 0, sec = 0, year = 0, month = 0, date = 0, bflag = 0;
|
|
|
vu16 timeoutaaa = 0, kgaaa = 0;
|
|
|
|
|
|
void wifitime_dingshiqi(void)
|
|
|
{
|
|
|
|
|
|
if (timeoutaaa)
|
|
|
timeoutaaa--;
|
|
|
kgaaa++;
|
|
|
if (kgaaa > 999)
|
|
|
{
|
|
|
kgaaa = 0;
|
|
|
sec++;
|
|
|
if (sec > 59)
|
|
|
{
|
|
|
sec = 0;
|
|
|
min++;
|
|
|
if (min > 59)
|
|
|
{
|
|
|
min = 0;
|
|
|
hour++;
|
|
|
if (hour > 23)
|
|
|
{
|
|
|
hour = 0;
|
|
|
bflag = 0; // 第二天重新同步时间
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
vu8 flagd = 0;
|
|
|
vu8 yali; // 血压或压力值
|
|
|
int main(void)
|
|
|
{
|
|
|
u16 i = 0;
|
|
|
Delay_Init(72);
|
|
|
USART1_Init(115200);
|
|
|
Delay_nMS(100);
|
|
|
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
|
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
|
|
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
|
|
PBout(0) = 1;
|
|
|
PBout(1) = 1;
|
|
|
PBout(2) = 1;
|
|
|
PBout(3) = 1;
|
|
|
PBout(4) = 1;
|
|
|
PBout(5) = 1;
|
|
|
PBout(6) = 1;
|
|
|
PBout(7) = 1;
|
|
|
beepa = 1;
|
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
|
|
|
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
|
|
|
// 发送字符串到电脑代表初始化成功
|
|
|
sendstr(1, "uart init ok!\r\n");
|
|
|
OV2640_HW_Init(); // IIC初始化
|
|
|
memset(&OV2640_Camera_ID, 0x0, sizeof(OV2640_IDTypeDef)); // 申请内存
|
|
|
sendstr(1, "uart IIC ok!\r\n"); // 串口发送字符串
|
|
|
|
|
|
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 分组2
|
|
|
OV2640_ReadID(&OV2640_Camera_ID); // 读取OV2640ID,测试硬件,依次为:0x7F,0xA2,0x26,0x42
|
|
|
|
|
|
OV2640_JPEGConfig(JPEG_160x120); // 配置OV2640输出320*240像素的JPG图片
|
|
|
// 设置自动曝光和白平衡
|
|
|
OV2640_BrightnessConfig(0x20);
|
|
|
OV2640_AutoExposure(2);
|
|
|
|
|
|
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 分组2
|
|
|
|
|
|
OV2640_CaptureGpioInit(); // 数据采集引脚初始化(外部中断)
|
|
|
EXTI->IMR &= ~EXTI_Line8; // 关闭场同步中断
|
|
|
EXTI->EMR &= ~EXTI_Line8;
|
|
|
|
|
|
EXTI->IMR &= ~EXTI_Line15; // 关闭像素同步中断
|
|
|
EXTI->EMR &= ~EXTI_Line15;
|
|
|
|
|
|
Delay_nMS(10); // 等待图像输出稳定
|
|
|
EXTI->IMR |= EXTI_Line8; // 使能场同步中断,准备下次采集
|
|
|
EXTI->EMR |= EXTI_Line8;
|
|
|
set(PA, 8, out); // led指示灯
|
|
|
set(PB, 9, od);
|
|
|
set(PA, 4, out);
|
|
|
set(PA, 7, od);
|
|
|
Tim1_Init(1);
|
|
|
USART2_Init(9600);
|
|
|
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 分组2
|
|
|
SysRead();
|
|
|
beepa = 1;
|
|
|
for (i = 0; i < 6; i++)
|
|
|
{
|
|
|
if (sys[i] > 99) // 超过99,则APP图像就不能正常显示
|
|
|
sys[i] = 99;
|
|
|
}
|
|
|
/*
|
|
|
基于单片机的宠物喂食系统:温度采集,可以手动或者定时投喂,视频监控。蓝牙远程控制喂食,app端设置阈值,显示温度。摄像头监测食物量上传图像处理,温湿度采集
|
|
|
*/
|
|
|
while (1)
|
|
|
{
|
|
|
|
|
|
if ((hour == sys[2]) && (min == sys[3])) // 如果定时时间到了
|
|
|
{
|
|
|
// 如果条件满足
|
|
|
if (flagd == 0)
|
|
|
{
|
|
|
flagd = 1;
|
|
|
duoji(0, ON); // 打开舵机1,底层在duoji.h,如果是51,你需要这样操作,因为瞬间电流太大
|
|
|
delayms(100); // 延时函数,单位ms
|
|
|
duoji(0, OFF); // 关闭舵机1
|
|
|
}
|
|
|
}
|
|
|
else // 否则
|
|
|
{
|
|
|
flagd = 0;
|
|
|
}
|
|
|
|
|
|
// 压力电阻2个脚,一个接G,一个接比如PA0,那么你从电阻包拿出电阻100-150K一个电阻,焊接在PA0跟V脚之间
|
|
|
// 如何焊接参考宝贝图,https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-5546754342.46.3af62742limxAv&id=634569036599
|
|
|
yali = 98 - GetADCResult(6, 1); // 3代表用PA3脚(STM32)或者12C的P13(C51不能用),没压力yali=0,压力越大值越大
|
|
|
if (Uart_RecOk) // 收到数据
|
|
|
{
|
|
|
Uart_RecOk = 0; // 清除标志
|
|
|
|
|
|
if ((Uart_Rx1[1] == 'k') && (Uart_Rx1[2] == '1'))
|
|
|
{
|
|
|
sys[0] = (Uart_Rx1[4] - 48) * 10 + (Uart_Rx1[5] - 48); // 吧数组的值存入sys数组
|
|
|
SysSave(); // 保存参数
|
|
|
}
|
|
|
if ((Uart_Rx1[1] == 'k') && (Uart_Rx1[2] == '2'))
|
|
|
{
|
|
|
sys[1] = (Uart_Rx1[4] - 48) * 10 + (Uart_Rx1[5] - 48); // 吧数组的值存入sys数组
|
|
|
SysSave(); // 保存参数
|
|
|
}
|
|
|
if ((Uart_Rx1[1] == 'k') && (Uart_Rx1[2] == '3'))
|
|
|
{
|
|
|
sys[2] = (Uart_Rx1[4] - 48) * 10 + (Uart_Rx1[5] - 48); // 吧数组的值存入sys数组
|
|
|
sys[3] = (Uart_Rx1[7] - 48) * 10 + (Uart_Rx1[8] - 48); // 吧数组的值存入sys数组
|
|
|
SysSave(); // 保存参数
|
|
|
}
|
|
|
|
|
|
|
|
|
if ((Uart_Rx1[1] == 'k') && (Uart_Rx1[2] == '4'))
|
|
|
{
|
|
|
hour = (Uart_Rx1[4] - 48) * 10 + (Uart_Rx1[5] - 48); // 吧数组的值存入sys数组
|
|
|
min = (Uart_Rx1[7] - 48) * 10 + (Uart_Rx1[8] - 48); // 吧数组的值存入sys数组
|
|
|
SysSave(); // 保存参数
|
|
|
}
|
|
|
|
|
|
if (strstr((const char *)&Uart_Rx1[0], "k5")) // 收到指定的命令
|
|
|
{
|
|
|
duoji(0, ON); // 打开舵机1,底层在duoji.h,如果是51,你需要这样操作,因为瞬间电流太大
|
|
|
delayms(100); // 延时函数,单位ms
|
|
|
duoji(0, OFF); // 关闭舵机1
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ((VsyncActive == 2) && (timeout == 0))
|
|
|
{
|
|
|
|
|
|
if ((JpegBuffer[0] == 0xff) && (JpegBuffer[1] == 0xd8) && (JpegDataCnt > 0) && (JpegDataCnt < 5230))
|
|
|
{ // 串口命令,一直发
|
|
|
|
|
|
DH11_GetTempDamp();
|
|
|
timeout = 500;
|
|
|
led = ~led;
|
|
|
// 不需要转BASE64
|
|
|
sendchar(1, TempNow / 10 + 48);
|
|
|
sendchar(1, TempNow % 10 + 48);
|
|
|
sendchar(1, DampNow / 10 + 48);
|
|
|
sendchar(1, DampNow % 10 + 48);
|
|
|
sendchar(1, yali / 10 + 48);
|
|
|
sendchar(1, yali % 10 + 48);
|
|
|
sendchar(1, hour / 10 + 48);
|
|
|
sendchar(1, hour % 10 + 48);
|
|
|
sendchar(1, min / 10 + 48);
|
|
|
sendchar(1,min % 10 + 48);
|
|
|
for (i = JpegDataCnt; i < (JpegDataCnt + 4); i++)
|
|
|
JpegBuffer[i] = 0;
|
|
|
|
|
|
if (JpegDataCnt % 3)
|
|
|
JpegDataCnt = JpegDataCnt + (3 - (JpegDataCnt % 3));
|
|
|
|
|
|
for (i = 0; i < JpegDataCnt; i++)
|
|
|
{
|
|
|
// 3个字节可以变成4个BASE64
|
|
|
base64_encode((const char *)&JpegBuffer[i], 3, (char *)&dat11[0], &len);
|
|
|
sendchar(1, dat11[0]);
|
|
|
sendchar(1, dat11[1]);
|
|
|
sendchar(1, dat11[2]);
|
|
|
sendchar(1, dat11[3]);
|
|
|
i += 2;
|
|
|
}
|
|
|
}
|
|
|
JpegDataCnt = 0; // JPEG计数器清零
|
|
|
|
|
|
EXTI->IMR |= EXTI_Line8; // 使能场同步中断,准备下次采集
|
|
|
EXTI->EMR |= EXTI_Line8;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
vu8 z1a = 0;
|
|
|
void TIM1_UP_IRQHandler(void)
|
|
|
{
|
|
|
|
|
|
if (TIM == TIM1)
|
|
|
{
|
|
|
if (TIM_GetITStatus(TIM, TIM_IT_Update) != RESET) // 判断是否为 更新事件 标志位
|
|
|
{
|
|
|
TIM_ClearITPendingBit(TIM, TIM_IT_Update); // 清除 更新事件 标志
|
|
|
if (timeout) // 倒计时不为0
|
|
|
{
|
|
|
timeout--; // 倒计时减1
|
|
|
}
|
|
|
wifitime_dingshiqi();
|
|
|
z1a++;
|
|
|
if (z1a > 99) // 定时100ms
|
|
|
{
|
|
|
z1a = 0; // 清零变量
|
|
|
if ((TempNow > sys[0]) || (DampNow > sys[1])) // 满足条件
|
|
|
beepa = ~beepa; // 蜂鸣器滴滴
|
|
|
else
|
|
|
beepa = 1; // 关闭蜂鸣器
|
|
|
}
|
|
|
|
|
|
if (timeout3) // 用于串口2 延时
|
|
|
timeout3--;
|
|
|
if (UartFlag_RecTime) // 从接收第一个有效字节开始,进行一秒的倒计时,如果没收到完整的
|
|
|
// 复位接收器,并发送一个字节的报错数据0x88.
|
|
|
{
|
|
|
if (RecTimeCount > 0)
|
|
|
RecTimeCount--;
|
|
|
else
|
|
|
{
|
|
|
UartRecInit = 0;
|
|
|
UartFlag_RecTime = 0; // 禁止接收倒计时
|
|
|
Uart_RecOk = 1;
|
|
|
}
|
|
|
}
|
|
|
if (UartFlag_RecTime2) // 从接收第一个有效字节开始,进行一秒的倒计时,如果没收到完整的
|
|
|
// 复位接收器,并发送一个字节的报错数据0x88.
|
|
|
{
|
|
|
if (RecTimeCount2 > 0)
|
|
|
RecTimeCount2--;
|
|
|
else
|
|
|
{
|
|
|
UartRecInit2 = 0;
|
|
|
UartFlag_RecTime2 = 0; // 禁止接收倒计时
|
|
|
Uart_RecOk2 = 1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @brief Inserts a delay time.
|
|
|
* @param nCount: specifies the delay time length.
|
|
|
* @retval None
|
|
|
*/
|
|
|
void Delay(__IO uint32_t nCount) // 延时1ms函数
|
|
|
{
|
|
|
for (; nCount != 0; nCount--)
|
|
|
;
|
|
|
}
|