资讯详情

毕业设计硬件代码

main函数

#include "stm32f10x.h" #include "delay.h" #include "usart.h" #include "led.h" #include "BH1750.h" #include "dht11.h" #include "lcd1602.h" #include "IIC.h" #include "pwm_output.h" #include "key.h" #include "adc.h" u8 temp;   //unsigned char无符号字节型,8位 u8 humi; int speed=52; extern unsigned char revaa[100];   //exern在其他文件中,变量或函数的定义提示编译器在其他模块中找到其定义 extern float lux; u16 adcx; int main(void) { 
          int worn=0;   int temp_bai,temp_shi,temp_ge;   ///温度,十,百  int humi_bai,humi_shi,humi_ge;   //湿度,十,百  int guang_bai,guang_shi,guang_ge;   ///光线,十,百  int speed_bai,speed_shi,speed_ge;   ///可能是电机的速度    delay_init();   ///延迟函数  Adc_Init();/span> //将模拟形式的连续信号转换为数字形式的离散信号 uart_init(115200); //串口初始化函数,串口初始化为9600 Init_LEDpin(); GPIO_Configuration(); //配置GPIO,通用输入/输出端口,通俗地说,就是一些引脚,可以通过它们输出高低电平或者通过它们读入引脚的状态-是高电平或是低电平。 LCD1602_Init();   //液晶初始化函数 BH1750_Init(); //光照强度函数 TIM3_PWM_Init(); //PWM初始化函数定义。PWM是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术 [PWM](https://www.cnblogs.com/brianblog/p/7117896.html) KEY_Init(); //按键初始化 [key](https://blog.csdn.net/qq_47348951/article/details/113078914) printf("AT+RST\r\n"); //重启模块 delay_ms(3000); //单片机执行命令的速度太快,加入延时来放慢端口电平的变化速度 delay_ms(3000); printf("AT+CIPMUX=1\r\n"); //开启多连接模式,可支持多个客户端的连接 delay_ms(3000); delay_ms(3000); printf("AT+CIPSERVER=1,8089\r\n"); //开启服务器,并监听8089端口 delay_ms(3000); delay_ms(3000); while(DHT11_Init())//温湿度传感器 { 
         } while(1) { 
         adcx=Get_Adc_Average(ADC_Channel_1,10); //得到ADC转换值  speed_bai=adcx/100; speed_shi=adcx%100/10; //%求余数 /除法 speed_ge=adcx%10; DHT11_Read_Data(&temp,&humi); //[温湿度传感器DHT11,从DHT11读取一次数据](https://blog.csdn.net/qq_42930154/article/details/104532523) temp_bai=temp/100; temp_shi=temp%100/10; temp_ge=temp%10; humi_bai=humi/100; humi_shi=humi%100/10; humi_ge=humi%10; //显示屏显示的数据//T:029H:075G:079 //PM:052  LCD1602_Show_String(0,0,2,"T:"); //调用函数(表示字符在LCD显示的横轴x的起始坐标,y,长度,数值) LCD1602_Show_Num(2,0,temp_bai); //调用函数,输入值,让显示屏显示即可 LCD1602_Show_Num(3,0,temp_shi); LCD1602_Show_Num(4,0,temp_ge); LCD1602_Show_String(5,0,2,"H:"); LCD1602_Show_Num(7,0,humi_bai); LCD1602_Show_Num(8,0,humi_shi); LCD1602_Show_Num(9,0,humi_ge); // printf("H:%d\r\n",humi);  BH1750_ReadContinuous1(); //调用光照强度的函数 printf("AT+CIPSEND=0,38\r\n"); //将一些传感器数据发送到TCP服务器,不知道是怎么发的“\ r”是回车符,“\ n”是新行 delay_ms(20); //printf("temp:%d--humi:%d--lux:%d--dat:%d",temp,humi,(int)lux,speed); printf("温度:%2d\r\n湿度:%2d\r\n光照:%3d\r\nPM2.5:%2d\r\n",temp,humi,(int)lux,adcx); //这个是在手机app上的,lux是光照,adcx是pm2.5 delay_ms(200); guang_bai=(int)lux/100; guang_shi=(int)lux%100/10; guang_ge=(int)lux%10; LCD1602_Show_String(10,0,2,"G:"); LCD1602_Show_Num(12,0,guang_bai); LCD1602_Show_Num(13,0,guang_shi); LCD1602_Show_Num(14,0,guang_ge); LCD1602_Show_String(0,1,3,"PM:"); //有参数可以看出在第二行了 LCD1602_Show_Num(3,1,speed_bai); LCD1602_Show_Num(4,1,speed_shi); LCD1602_Show_Num(5,1,speed_ge); if(revaa[10]=='1')//开灯 { 
         revaa[10]=0xff; GPIO_ResetBits(GPIOC,GPIO_Pin_13); //reset为0 //LED灯 } if(revaa[10]==0x32)//关灯 { 
         revaa[10]=0xff; //全为1,高电平,不知道什么意思 GPIO_SetBits(GPIOC,GPIO_Pin_13); //set为1 //LED灯 } if(revaa[10]==0x33)//开风扇 { 
         revaa[10]=0xff; GPIO_SetBits(GPIOC,GPIO_Pin_14); //LED灯 } if(revaa[10]==0x34)//关风扇 { 
         revaa[10]=0xff; GPIO_ResetBits(GPIOC,GPIO_Pin_14); //LED灯 } if(revaa[10]==0x35)//开加湿器 { 
         revaa[10]=0xff; GPIO_SetBits(GPIOC,GPIO_Pin_15); //LED灯 } if(revaa[10]==0x36)//关加湿器 { 
         revaa[10]=0xff; GPIO_ResetBits(GPIOC,GPIO_Pin_15); //LED灯 } if(revaa[10]==0x37)//开窗帘 { 
         revaa[10]=0xff; GPIO_SetBits(GPIOA,GPIO_Pin_0); //set是设置为1 //LED灯 } if(revaa[10]==0x38)//关窗帘 { 
         revaa[10]=0xff; GPIO_ResetBits(GPIOA,GPIO_Pin_0); //reset就是设置为0 //LED灯 } } } 

usart文件(向串口发送字节数据函数,配置串口1和串口2,向串口发送字符串数据函数(单片机发给WiFi模块),串口1中断服务程序(WiFi模块发给单片机控制指令后产生中断))

#include "sys.h"
#include "usart.h" 
#include "stdio.h"
#include "string.h"
#include "stm32f10x_tim.h"
unsigned char uart1_getok;
//
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1 /*printf() 之类的函数,使用了半主机模式。使用标准库会导致程序无法运行,为了继续使用标准库 ,要添加下面代码,为确保没有从 C 库链接使用半主机的函数,因为不使用半主机,标准 C 库 stdio.h 中有些使用半主机的 函数要重新写 ,您必须为这些函数提供自己的实现 */
#pragma import(__use_no_semihosting) // 确保没有从 C 库链接使用半主机的函数 
struct __FILE   //标准库需要的支持函数 
{ 
        
	int handle; 
}; 
[相关链接](https://blog.csdn.net/tao658/article/details/81204094)

unsigned char revaa[100];
int revaa_num=0;
FILE __stdout;       

_sys_exit(int x)    //定义—sys_exit()以避免使用半主机模式 
{ 
        
	x = x; 
} 
//重定义fputc函数。标准库函数的默认输出设备是显示器, 要实现在串口或 LCD 输出,必须重定义标准库函数里调用的与输出,printf 输出到串口,需要将 fputc 里面的输出指向串口 (重定向 ),链接在上面
int fputc(int ch, FILE *f)
{ 
             
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 &0X40就是让SR寄存器的第七位置一
    USART1->DR = (u8) ch;      
	return ch;
}
[链接](http://www.openedv.com/posts/list/29268.htm)

#endif 

void UART1_send_byte(char data)   //STM32串口发送字节数据
{ 
       
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //USART_GetFlagStatus获取串口相关的状态寄存器信息的等待发送完成。 检测 USART_FLAG_TXE是否置1
	USART_SendData(USART1, data);   通过库函数 向串口1发送数据
}
void UART2_send_byte(char data)
{ 
       
	while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
	USART_SendData(USART2, data);
}

//PC上位机模块PC上位机模块实现PC机对步进电机的控制。利用MSP430单片机的USART模块实现与PC上位机的通信,PC机通过串口向单片机发送控制命令,实现电机控制。单片机所接收到控制命令暂存在RXBUFFER中,然后与存储在片内Flash的中断程序的入口地址相比较,相同就进入中断,实现步进电机的控制。
//串口1中断服务程序
//注意,读取USARTx——>SR能避免莫名其妙的错误
unsigned char RxCounter,RxBuffer[255];     //接受缓冲,最大255个字节
char RxCounter1,RxBuffer1[100];     //接收缓冲,最大100个字节。
接收状态
//bit15, 接收完成标志0x0a
//bit14, 接收到0X0d标志
//bit13~0, 接收到的有效数据个数
u16 USART_RX_STA=0;       //接收状态标记,没有用到 
extern u8 Timeout;
//初始化IO串口1
//bound:波特率
void uart_init(u32 bound){ 
          //串口初始化函数
   //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能UsART1,GPTOA时钟
 	USART_DeInit(USART1);  //复位串口1
	 //USART1_TX PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 GPIOA.9
   
    //USART1_RX PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//USART1_RX PA.10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化 GPIOA.10

   //Usart1 NVIC配置

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIc寄存器,//中断优先级初始化

  
  //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//波特率设置,一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

    USART_Init(USART1, &USART_InitStructure); //初始化串口
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断
    USART_Cmd(USART1, ENABLE);                    //使能串口

}
//初始化Io串2
//bound:波特率
void uart2_init(u32 bound)
{ 
       
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//使能,GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//USART2
 	USART_DeInit(USART2);  //复位串口2
	 //USART2_TX PA.2
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA2
   
    //USART2_RX PA.3
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA3

  //Usart1 NvIC配置

    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化vIc寄存器
  
   //USART初始化设置

	USART_InitStructure.USART_BaudRate = bound;//115200
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字节为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
    USART_Init(USART2, &USART_InitStructure); //初始化串口
		
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启中断
    USART_Cmd(USART2, ENABLE);                    //使能串口

}
[上面两段很长的代码,就是串口1和串口2的初始化](https://blog.csdn.net/qq_46626969/article/details/107220770)


void Uart1_SendStr(char*SendBuf)// 向串口1打印数据(发送字符串函数)
{ 
       
	while(*SendBuf)
	{ 
       
        while((USART1->SR&0X40)==0);//等待发送完成,要检测这个数据是否已经被发送完成了通过之后,要检测这个数据是否已经被发送完成了通过之后,要检测这个数据是否已经被发送完成了通过USART1->SR的第6位,是否为1来决定是否可以开始第二个字节的发送。0x40二进制是1000000
        USART1->DR = (u8) *SendBuf; //USART1->DR是一个数据寄存器,包括TDR和RDR,当向该数据寄存器写数据的时候,会自动向串口发送数据,这句话就是将接收缓存送至该数据寄存器,同时发送到串口。
        SendBuf++;
	}
}


void USART1_IRQHandler(void)                	//串口1中断服务程序
{ 
       
	u8 Res;


	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)(0x0D是回车的ASCLL码,0x0A是换行的ASCLL码)
	{ 
       
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
			if(Res==0x2b)
			{ 
       
				revaa_num=0;
			}
			revaa[revaa_num]=Res;
			revaa_num++;
				

		
     } 
	
[相关代码](https://blog.csdn.net/milu_yu/article/details/108523888)
} 

delay文件(头文件,调度,开锁调度,延时函数,初始化延时函数,不使用ucos系统时和使用ucos系统的延时函数,其中还有ms和ns的两种情况)

//当使用ucos时才有以下部分:主要实现宏定义与基本函数定义。
#include "delay.h"

//如果需要使用os,则包括下面的头文件即可,os是操作系统的意思
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos 使用 
#endif


static u8  fac_us=0;							//us延时倍乘数 
static u16 fac_ms=0;							//us延时倍乘数,在ucos下,代表每个节拍的ms数
	
	
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS定义了,说明要支持OS了(不限于UCOS).
//当delay_us/delay_ms需要支持OS的时候需要三个与OS相关的宏定义和函数来支持
//首先是3个宏定义:
// delay_osrunning:用于表示OS当前是否正在运行,以决定是否可以使用相关函数
//delay_ostickspersec:用于表示OS设定的时钟节拍,delay_init将根据这个参数来初始哈systick
// delay_osintnesting:用于表示OS中断嵌套级别,因为中断里面不可以调度,delay_ms使用该参数来决定如何运行
//然后是3个函数:
// delay_osschedlock:用于锁定OS任务调度,禁止调度
//delay_osschedunlock:用于解锁OS任务调度,重新开启调度
// delay_ostimedly:用于OS延时,可以引起任务调度.

//[ucos是一个操作系统,两个版本:UCOSII和UCOSIII](https://blog.csdn.net/weixin_38847128/article/details/84391783)
//本例程仅作UCOSII和UCOSIII的支持,其他OS,请自行参考着移植
//支持UCOSII
#ifdef OS_CRITICAL_METHOD //OS_CRITICAL_METHOD定义了,说明要支持UCOSII 
#define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行
#define delay_ostickspersec OS_TICKS_PER_SEC //OS时钟节拍,即每秒调度次数
#define delay_osintnesting OSIntNesting //中断嵌套级别,即中断嵌套次数
#endif

//支持UCOSIII
#ifdef CPU_CFG_CRITICAL_METHOD //CPU_CFG_CRITICAL_METHOD定义了,说明要支持UCOSIII
#define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行
#define delay_ostickspersec OSCfg_TickRate_Hz //OS时钟节拍,即每秒调度次数
#define delay_osintnesting OSIntNestingCtr //中断嵌套级别,即中断嵌套次数
#endif

//OSSchedLock()和OSSchedUnlock()函数允许应用程序锁定当前任务不被其它任务抢占,两个函数成对出现
//us级延时时,关闭任务调度(防止打断us级延迟)用于锁定os任务调度,禁止调度
void delay_osschedlock(void)

标签: ed灯c显示器d传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台