newlab平台stm32总结

详细资源包下载:点击此处

一、GPIO的输出

1.时钟设置
2.调用初始化函数
3.输出函数
(1)GPIO_WriteBit(端口,引脚,(BitAction)(0));//低
GPIO_WriteBit(端口,引脚,(BitAction)(1));//高
(2)GPIO_SetBits(端口,引脚); //低
GPIO_ResetBits端口,引脚); //高
(3)PAout(n) = 1:PAn;//输出高
PAout(n) = 0;//输出低
P端口out(引脚) = 0|1
(4)PAin(n) = 1;//输入高
PAin(n) = 0;//输入低
P端口in(引脚) = 0|1

void Init(void){ //初始化
	GPIO_InitTypeDef  GPIO_InitStructure; 	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//参数一:GPIOB口输出,参数二:使能       
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;//B0和B1                        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出频率
	GPIO_Init(LEDPORT, &GPIO_InitStructure);//初始化			
}

用途

例一:
点亮led

步骤:
1.初始化时钟
2.初始化PB0,1
3.调用GPIO输出函数
连接方式:
位数码管连接3.3v
段数码管连接PB0



#define LEDPORT	GPIOB	
#define LED1	GPIO_Pin_0	
#define LED2	GPIO_Pin_1	
void LED_Init(void){
	GPIO_InitTypeDef  GPIO_InitStructure; 	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);       
    GPIO_InitStructure.GPIO_Pin = LED1 | LED2;                       
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     
	GPIO_Init(LEDPORT, &GPIO_InitStructure);			
}

int Led1(){
	RCC_Configuration();
	LED_Init();
	while(1){
		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0));//低电平亮,高电平灭
		delay_ms(100);
		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1));
		delay_ms(100);
	}
}
按键控制Led

步骤:
1.初始化按键
2.获取按键电平
GPIO_ReadInputDataBit(KEYPORT1,KEY1)
按下返回低电平0,松开返回高电平1

连接方式:

//按键1 C13
#define KEYPORT1	GPIOC	
#define KEY1	GPIO_Pin_13	

//按键2 D13
#define KEYPORT2 GPIOD
#define KEY2	GPIO_Pin_13
void KEY1_Init(void){ 
	GPIO_InitTypeDef  GPIO_InitStructure; 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);       
    GPIO_InitStructure.GPIO_Pin = KEY1;       
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;       
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
	GPIO_Init(KEYPORT1,&GPIO_InitStructure);			
}
 
void KEY2_Init(void){ 
	GPIO_InitTypeDef  GPIO_InitStructure; 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);       
    GPIO_InitStructure.GPIO_Pin = KEY2;                
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(KEYPORT2,&GPIO_InitStructure);			
}
例二:蜂鸣器

步骤:
1.初始化时钟
2.初始化PB5
3.调用GPIO输出函数
连接方式:

#define BUZZERPORT	GPIOB
#define BUZZER	GPIO_Pin_5
void BUZZER_Init(void){ 
	GPIO_InitTypeDef  GPIO_InitStructure; 	
    GPIO_InitStructure.GPIO_Pin = BUZZER;                      
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(BUZZERPORT, &GPIO_InitStructure);	
	GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(1));		
}
void BUZZER_BEEP1(void){
	u16 i;
	for(i=0;i<200;i++){
		GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(0)); 
		delay_us(500); 
		GPIO_WriteBit(BUZZERPORT,BUZZER,(BitAction)(1)); 
		delay_us(500);		
	}
}
例三:点亮动态数码管

步骤:
1.初始化时钟
2.初始化PB0,1,2,3,4,5,6,7
3.调用GPIO输出函数
连接方式:
数码管段选输出口为PA0-7,位选输出口为PB10-13 PC6-9

void GPIO_Configuration(void)//时钟配置子程序
{
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构变量
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5|GPIO_Pin_4|GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0; 
	GPIO_Init(GPIOA,&GPIO_InitStructure); 
	
	GPIO_SetBits(GPIOA,GPIO_InitStructure.GPIO_Pin); 
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13; 
	GPIO_Init(GPIOB,&GPIO_InitStructure); 
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_8|GPIO_Pin_7|GPIO_Pin_6; 
	GPIO_Init(GPIOC,&GPIO_InitStructure); 
	
	GPIO_SetBits(GPIOB,GPIO_InitStructure.GPIO_Pin); 

}

void Show_Num(double num){
	
		double num1 = num;
		unsigned char index = 0;
		unsigned int n = 1;
		unsigned int num2;
		unsigned char i;
		while((unsigned int)num1 != num1&&index < 4){
			index++;
			num1 = num1*10;
			n = n*10;
		}
		num2 = num1;
		LedOut[0]=Disp_Tab[num2/10000000%10]; 
		LedOut[1]=Disp_Tab[num2/1000000%10];   
		LedOut[2]=Disp_Tab[num2/100000%10];	
		LedOut[3]=Disp_Tab[num2/10000%10];	 
	
		LedOut[4]=Disp_Tab[num2/1000%10];
		LedOut[5]=Disp_Tab[num2/100%10];
		LedOut[6]=Disp_Tab[num2/10%10];
		LedOut[7]=Disp_Tab[num2%10];     
		LedOut[7-index]=Disp_Tab1[num2/n%10];
		
		
		
		for(i=0; i<8; i++) 
		{		
			GPIO_Write(GPIOA , LedOut[i])	;	
			LED1(0);LED2(0);LED3(0);LED4(0);LED5(0);LED6(0);LED7(0);LED8(0);
			switch(i)					  
			{
				case 0:	
					LED1(1);LED2(0);LED3(0);LED4(0);LED5(0);LED6(0);LED7(0);LED8(0);
					break;         
				case 1:
					LED1(0);LED2(1);LED3(0);LED4(0);LED5(0);LED6(0);LED7(0);LED8(0);
					break;             	
				case 2:
					LED1(0);LED2(0);LED3(1);LED4(0);LED5(0);LED6(0);LED7(0);LED8(0);
					break; 
				case 3:
					LED1(0);LED2(0);LED3(0);LED4(1);LED5(0);LED6(0);LED7(0);LED8(0);
					break;
				case 4:	
					LED1(0);LED2(0);LED3(0);LED4(0);LED5(1);LED6(0);LED7(0);LED8(0);
					break; 
				case 5:	
					LED1(0);LED2(0);LED3(0);LED4(0);LED5(0);LED6(1);LED7(0);LED8(0);
					break; 
				case 6:
					LED1(0);LED2(0);LED3(0);LED4(0);LED5(0);LED6(0);LED7(1);LED8(0);
					break;
				case 7:	
					LED1(0);LED2(0);LED3(0);LED4(0);LED5(0);LED6(0);LED7(0);LED8(1);
					break; 
			 }
			delay_nms(1); 
		}
	
}

#include "stm32f10x.h"                  // Device header
#include "dynamic_seg_led.h"
int main(void)
{
	RCC_Configuration1();//配置时钟
	GPIO_Configuration();//配置GPIO口
	LED1(0);LED2(0);LED3(0);LED4(0);LED5(0);LED6(0);LED7(0);LED8(0);//熄灭所有数码管
	while(1){
          Show_Num(1234.5678);//显示想显示的数
	}
}

例四: 驱动灯泡,风扇,门锁

步骤:
与例一相同
线路连接:
GPIO输出口连接继电器J2(J5),J9(J12)连接设备正极,J8(J11)连接电源正极12V,设备负极连接电源负极

例五: 键盘模块

步骤:
1.时钟设置
2.44或55键盘初始化
3.获取按键信息,如将获取的信息显示在数码管上
连线:
4*4键盘
COL0-COL3 PB10-PB13
ROW0-ROW3 PC6-PC9
在这里插入图片描述

5*5键盘
ROW0-ROW4 PA0-PA4
COL4-COL0 PB14-PB10
在这里插入图片描述

//键盘初始化
void GPIO_Configuration55(void)
{

	
		GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构变量
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启PA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启PB时钟
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //开启PC时钟
		
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_1|GPIO_Pin_0;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //配置成推挽输出
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出速度 50M HZ
		GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA口

  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 |  GPIO_Pin_11 |  GPIO_Pin_12 |  GPIO_Pin_13 |  GPIO_Pin_14;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //上拉输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //
    GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化PB口
		GPIO_Write(GPIOB, 0x7C00); //上拉输入需要把对应的ODR置1

 }

/*
5*5矩阵按键设置
*/
 int  keyscan55(void)
 { 	
	 ROW14(0);ROW13(0);ROW12(0);ROW11(0);ROW10(0);//ÐÐÏßÀ­µÍ
//  		    |			|			|			|     |
// 0 PA0 ---0-----1-----2-----3-----4-- |  		|--------|
//	  	    |			|			|			|     |   --------
// 0 PA1 ---5-----6-----7-----8-----9--
//	  	    |			|			|			|     |
// 0 PA2 ---A-----B-----C-----D-----E-- 
//	  	    |			|			|			|     |
// 0 PA3 ---F-----H-----I-----J-----K-- 
//	  	    |			|			|			|     |
// 0 PA4 ---L-----M-----N-----O-----P--
//          |     |     |     |     |
//	  		 PB14 PB13  PB12   PB11  PB10
//    
		if(COL14&&COL13&&COL12&&COL11&&COL10){
			return -1;
		}
		else
		{
			delay_nms(5); 
			if(COL14&&COL13&&COL12&&COL11&&COL10)
				return -1;
		}
		
//  		    |			|			|			|     |
// 0 PA0 ---0-----1-----2-----3-----4-- |  		|--------|
//	  	    |			|			|			|     |   --------
// 1 PA1 ---5-----6-----7-----8-----9--
//	  	    |			|			|			|     |
// 1 PA2 ---A-----B-----C-----D-----E-- 
//	  	    |			|			|			|     |
// 1 PA3 ---F-----H-----I-----J-----K-- 
//	  	    |			|			|			|     |
// 1 PA4 ---L-----M-----N-----O-----P--
//          |     |     |     |     |
//	  		 PB14 PB13  PB12   PB11  PB10
//    
		ROW14(1);ROW13(1);ROW12(1);ROW11(1);ROW10(0);
		if(!COL14){
			return 0;
		}
		if(!COL13){
			return 1;
		}
		if(!COL12){
			return 2;
		}
		if(!COL11){
			return 3;
		}
		if(!COL10){
			return 4;
		}
//  		    |			|			|			|     |
// 1 PA0 ---0-----1-----2-----3-----4-- |  		|--------|
//	  	    |			|			|			|     |   --------
// 0 PA1 ---5-----6-----7-----8-----9--
//	  	    |			|			|			|     |
// 1 PA2 ---A-----B-----C-----D-----E-- 
//	  	    |			|			|			|     |
// 1 PA3 ---F-----H-----I-----J-----K-- 
//	  	    |			|			|			|     |
// 1 PA4 ---L-----M-----N-----O-----P--
//          |     |     |     |     |
//	  		 PB14 PB13  PB12   PB11  PB10
//    
		ROW14(1);ROW13(1);ROW12(1);ROW11(0);ROW10(1);
		if(!COL14){
			return 5;
		}
		if(!COL13){
			return 6;
		}
		if(!COL12){
			return 7;
		}
		if(!COL11){
			return 8;
		}
		if(!COL10){
			return 9;
		}
		
//  		    |			|			|			|     |
// 1 PA0 ---0-----1-----2-----3-----4-- |  		|--------|
//	  	    |			|			|			|     |   --------
// 1 PA1 ---5-----6-----7-----8-----9--
//	  	    |			|			|			|     |
// 0 PA2 ---A-----B-----C-----D-----E-- 
//	  	    |			|			|			|     |
// 1 PA3 ---F-----H-----I-----J-----K-- 
//	  	    |			|			|			|     |
// 1 PA4 ---L-----M-----N-----O-----P--
//          |     |     |     |     |
//	  		 PB14 PB13  PB12   PB11  PB10
//    

		ROW14(1);ROW13(1);ROW12(0);ROW11(1);ROW10(1);
		if(!COL14){
			return 10;
		}
		if(!COL13){
			return 11;
		}
		if(!COL12){
			return 12;
		}
		if(!COL11){
			return 13;
		}
		if(!COL10){
			return 14;
		}
//  		    |			|			|			|     |
// 1 PA0 ---0-----1-----2-----3-----4-- |  		|--------|
//	  	    |			|			|			|     |   --------
// 1 PA1 ---5-----6-----7-----8-----9--
//	  	    |			|			|			|     |
// 1 PA2 ---A-----B-----C-----D-----E-- 
//	  	    |			|			|			|     |
// 0 PA3 ---F-----H-----I-----J-----K-- 
//	  	    |			|			|			|     |
// 1 PA4 ---L-----M-----N-----O-----P--
//          |     |     |     |     |
//	  		 PB14 PB13  PB12   PB11  PB10
//    

		ROW14(1);ROW13(0);ROW12(1);ROW11(1);ROW10(1);
		if(!COL14){
			return 15;
		}
		if(!COL13){
			return 16;
		}
		if(!COL12){
			return 17;
		}
		if(!COL11){
			return 18;
		}
		if(!COL10){
			return 19;
		}
 //  		    |			|			|			|     |
// 1 PA0 ---0-----1-----2-----3-----4-- |  		|--------|
//	  	    |			|			|			|     |   --------
// 1 PA1 ---5-----6-----7-----8-----9--
//	  	    |			|			|			|     |
// 1 PA2 ---A-----B-----C-----D-----E-- 
//	  	    |			|			|			|     |
// 1 PA3 ---F-----H-----I-----J-----K-- 
//	  	    |			|			|			|     |
// 0 PA4 ---L-----M-----N-----O-----P--
//          |     |     |     |     |
//	  		 PB14 PB13  PB12   PB11  PB10
//    

		ROW14(0);ROW13(1);ROW12(1);ROW11(1);ROW10(1);
		if(!COL14){
			return 20;
		}
		if(!COL13){
			return 21;
		}
		if(!COL12){
			return 22;
		}
		if(!COL11){
			return 23;
		}
		if(!COL10){
			return 24;
		}
		return -1;
}
 void delay_nms(u16 time)//ÑÓʱ×Ó³ÌÐò
{  u16 i=0;  
   while(time--)
   {  i=12000;  //×Ô¼º¶¨Òå
      while(i--) ; 
   }
}

#include "stm32f10x.h" //STM32
#include "matrix_key.h"
#include "usart.h"
// 此表为LED的字模         	   0	  1	2    3	   4	 5	6    7	   8	 9     a     b	   c	 d     e     f
unsigned char  LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};
int x;
int main(void){
	RCC_Configuration(); //时钟设置
	USART1_Init(115200); //串口初始化波特率
	GPIO_Configuration55();//GPIO_Configuration44();
	GPIO_Write(GPIOA, LED7Code[8]);//数码管全亮
  while(1)
  { 
		x=keyscan55();//扫描按键,返回按键值
          //x=keyscan44();)
		printf("%d ",x);//串口输出
		if (x>=0)
		{
			GPIO_Write(GPIOA, LED7Code[x]);	//显示按键值;				
		}
  }
}

二、LCD输出

步骤:
1.初始化LCD显示屏
2.清屏
3.写数据

LCD点阵大小 12864 即8行16列
每一个英文字符占8
16个字节,即2行1列,两行可以显示16个英文字符
每一个中文字符占16*16个字节,即2行2列,两行可以显示8个中文字符
如果超出不显示,以上为默认情况,其他函数详见LCD12864.c文档
可使用PCTOLCD生成需要的点阵

//LCD主函数
#include "stm32f10x.h"                  // Device header
#include "stm32f103_config.h"
#include "lcd12864.h"
#include "Font.h"
#include "Image.h"
int main(void)
{
	delay_ms(100);//延时100毫秒
	LCD_Init();/初始化显示屏
	LCD_Clr(); //清屏
	LCD_WriteEnglish(2,0,1+'0');
	LCD_WriteEnglish(2,8,2+'0');
	LCD_WriteEnglish(2,2*8,3+'0');
	LCD_WriteEnglish(2,3*8,4+'0');
	LCD_WriteEnglish(2,4*8,5+'0');
	LCD_WriteEnglishString(2,5*8,(unsigned char *)" end");
	LCD_WriteEnglishString(4,0,(unsigned char *)"0123456789ABCDEF");*/
	LCD_WriteEnglishString(0,0,(unsigned char *)" HUNAN CITY");
	LCD_WriteEnglishString(2,0,(unsigned char *)"  University");
	LCD_WriteChineseString(4,0,(unsigned char *)hanzi,6);
  //LCD_DispImg(2,48,60,60,(unsigned char *)Fig0);	
}

线路连接:
在这里插入图片描述

三、TFTLCD输出

NEWLab的TFT模块采用了ILI9341控制器,其外形如图85所示。该模块有如下特点:
2.8寸屏幕。 320×240的分辨率。 16位真彩显示。 自带触摸屏,可以用来作为控制输入

步骤:
与LCD相似
1.初始化TFTLCD
2.相关函数的使用如下代码
线路连接:
在这里插入图片描述
显示图片步骤:
1.打开Image2Lcd软件
2.点击右上角打开按钮,选择你要的图片
3.其他设置如下图
首先,按照图811所示,配置Image2LCD的工作模式。其中,
输出数据类型:“C语言数组(.C)”
扫描模式:水平扫描
输出灰度:16位真彩色
最大宽度和高度:与图片的大小和液晶屏的大小相匹配。
选择包含图像头数据
选择自底至顶扫描
注:像素大小不得超过240
320 若超过,请使用如"图画"软件缩减图片尺寸
在这里插入图片描述
4.创建一个img.h文件,将生成的c语言数组放入文件中,使用GLCD_DrawBitmap (0 ,0, 180, 240, (const uint8_t *)gImage_test)函数实现图像显示

#include "stm32f10x.h"                  // Device header
#include "GLCD_Config.h"
#include "Board_GLCD.h"
#include "img.h"
#include "delay.h"
#include "stdlib.h"
extern GLCD_FONT GLCD_Font_16x24;//外部字体变量
extern GLCD_FONT GLCD_Font_6x8;
uint32_t n;
double num;
char str[25];
int main(void)
{
	GLCD_Initialize();//初始化LCD
	GLCD_ClearScreen();//清屏
	GLCD_SetForegroundColor(GLCD_COLOR_BLACK);//前景颜色
	GLCD_SetBackgroundColor(GLCD_COLOR_WHITE);//背景颜色
	GLCD_SetFont(&GLCD_Font_16x24);//设置字体,高度25,宽度16
     //hight 24*13=312 < 320    lenth 16*15=240
	GLCD_ClearScreen();	//清屏
	
	//GLCD_SetForegroundColor(GLCD_COLOR_BLACK);
	//GLCD_DrawPixel(11,22);//1.绘制一个像素点
	//GLCD_DrawHLine(1,1,120);//2.绘制横线
	//GLCD_DrawVLine(1,1,120);//3.绘制竖线
	//GLCD_DrawHLine(1,120,120);
	//GLCD_DrawVLine(120,1,120);
	
	//4.绘制字符串
	num = 123.4567;
  sprintf(str, " %f" , num);
	GLCD_SetFont(&GLCD_Font_6x8);
	//GLCD_SetFont(&GLCD_Font_16x24);
												//hight 24*13=312 < 320    lenth 16*15=240
	GLCD_DrawString(24,24,str);
	//GLCD_DrawString(24, 24,"HuNan City");//
	
	//5.绘制矩形框
	//GLCD_SetForegroundColor(GLCD_COLOR_GREEN);//Ç°¾°£¨×Ö·û£©ÑÕɫΪÂÌÉ«
	//GLCD_DrawRectangle(10,10,120,120);
	
	//6.绘制线条,
	//GLCD_SetForegroundColor(GLCD_COLOR_BLACK);//
	//GLCD_DrawBargraph(30,0,200,40,10);//x,y,weight(0~240),height(0~320),val<100
	
	//7.绘制图像
	//GLCD_DrawBitmap (0 ,0, 180, 240, (const uint8_t *)gImage_test);//ÏÔʾͼÏñ
	//x,y,width(<=240),height(<=320)
	
	//8.向下滚动屏幕n个像素点,滚动条
	//GLCD_VScroll(12);
	//delay_s(1);
	//GLCD_VScroll(100);
	
  
	
	while(1)
	{		
         //GLCD_VScroll(40);
         //delay_s(1);
	}
}

三、串口输出

串口通信接口为USART
TX代表发送 RX代表接收
RX1 PA10 TX1 PA9 连接底部引脚 所以可以直接通过NEWLAB板通信
RX2 PA2 TX2 PA3
RX3 PB11 TX3 PB10

串口发送代码实现:
导入usart.c驱动文件,驱动文件已经设置好三个串口的引脚,只要在使用时更改定义的引脚即可,其他不需要改变
stm32中,c语言的printf函数被默认打印在串口上

串口接收代码实现
查询方式接收:将接收到的数据发送回电脑,usart.c文件中,在串口1初始化函数中,将USART_ITConfig是否开启串口中断函数的ENABLE改为DISABLE,防止调用中断函数

使用中断方式接收:可以在数据收到的第一时间,马上跳转到中断函数来做及时的处理,提高实时性


#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "usart.h"
#include "key.h"
extern unsigned char  LED7Code[];
int main (void){//
	u8 a;
	//初始化程序
	RCC_Configuration(); //时钟设置
	LED8_Init();//8位数码管初始化
	USART1_Init(115200); //串口初始化

 	while(1){
		//实现串口控制8位数码管
		if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) != RESET){  //查询串口标志位
			a = USART_ReceiveData(USART1);//读取接收到的数据
			printf("%c",a); //把收到的数据发送到电脑
			if(a>='0'&&a<='9'){
				GPIO_Write(GPIOA,LED7Code[a-'0']);//显示数字
			}
		}
		LATCH_KEY1();//按下key1,发送key1被按下信息
		LATCH_KEY2();//按下key2,发送key2被按下信息

//      delay_ms(1000); 
	}
}


用例

WIFI模块

步骤:
1.连接
2.平台命令获取及分析
3.单片机数据发送
接线:
stm32 P10 Tx - wifi RX
stm32 P11 Rx - wifi TX

int main()
{
	uint8_t IpData[128];
	int8_t temp;//检验热点是否连接成功,成功为1,失败为0
	uint8_t TryCount=0;
	RCC_Configuration(); //系统时钟初始化 
	TIM2_Init();
	USART1_Init(115200);//串口一初始化
	printf("init...\r\n");
	UART4_Init(115200);//WiFi串口四初始化
	for(TryCount=0; TryCount<3; TryCount++)//三次连接
	{
		printf("start link %d times.\r\n",TryCount+1);
		temp=ConnectToServer((char *)MY_DEVICE_ID, (char *)MA_SECRET_KEY);//连接热点和服务器
		if(temp != 0)//连接失败 temp = -1:WIFI模式设置错误 -2:WIFI连接错误 -3:端口或地址错误 -4:第一次握手数据发送错误 -5未响应错误
		{
			printf("Connect To Server ERROR=%d\r\n",temp);
		}
		else
		{
			break;
		}
	}
	printf("link success\r\n");
	ClrAtRxBuf();//清空AT缓存
	//==================以上为WIFI连接函数===========================

	while(1)
	{
	//===================以下为WIFI接收到云平台数据函数==================
		if(F_AT_RX_FINISH)//判断是否接收到UART4_RX数据
		{	 // 接收到数据包
			ESP8266_GetIpData((uint8_t *)AT_RX_BUF, (char *)IpData);//获取数据,存入IpData
			USER_DataAnalysisProcess((char *)IpData);//分析数据,在这个函数里对数据进行处理
			memset(IpData, 0x00, 128);//清空数据
			ClrAtRxBuf();
		}
		///==================已下为WIFI发送单片机数据到云平台函数==================
		if(TimeCount >= 1000)//10S发送一次数据 timeCount每计数100次代表1s
		{
			TimeCount=0;
			ESP8266_SendSensor((char *)"wind", (char *)"2020-10-16 14:10:26", GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0));//发送数据函数,参数1标识名 参数二:时间 参数三:数据如温度,低频高低
			ClrAtRxBuf();
		}
	}
	
}

//=================以下为分析函数具体实现============
void USER_DataAnalysisProcess(char *RxBuf)
{
	char *cmdid = NULL;
	uint8_t TxetBuf[128];//发送数据
	if(strstr((const char *)RxBuf, (const char *)PING_REQ) != NULL)//心跳请求//strstr()查找子串在主串第一次出现的位置,判断是否收到数据
	{
		if(ESP8266_IpSend((char *)PING_RSP, strlen((const char *)PING_RSP)) < 0)//响应心跳
		{//发送失败
			printf("发送心跳包失败!\r\n");
		}
		else
		{
			printf("心跳包!\r\n");
		}
	}
	else if(strstr((const char *)RxBuf, (const char *)"\"t\":5") != NULL)//命令请求//收到请求
	{
		if(strstr((const char *)RxBuf, (const char *)"\"apitag\":\"ctrl\"") != NULL)//判断收到的标识名
		{
			memset(TxetBuf,0x00,128);//清空缓存
///=====================操作代码书写区域=====================
			//==============判断收到的数据,在里面执行需要的操作==============
			if((strstr((const char *)RxBuf, (const char *)"\"data\":1") != NULL))
			{
				GPIO_SetBits(GPIOA,GPIO_Pin_0);
				cmdid = USER_GetJsonValue((char *)RxBuf, (char *)"cmdid");
				sprintf((char *)TxetBuf,"{\"t\":6,\"cmdid\":%s,\"status\":0,\"data\":1}",cmdid);
				//printf("%s\r\n",TxetBuf);
				if(ESP8266_IpSend((char *)TxetBuf, strlen((char *)TxetBuf)) < 0)
				{//发送失败
					//printf("发送响应失败!\r\n");
				}
			}
			else if((strstr((const char *)RxBuf, (const char *)"\"data\":0") != NULL))//关灯
			{
				GPIO_ResetBits(GPIOA,GPIO_Pin_0);
				cmdid = USER_GetJsonValue((char *)RxBuf, (char *)"cmdid");
				sprintf((char *)TxetBuf,"{\"t\":6,\"cmdid\":%s,\"status\":0,\"data\":0}",cmdid);
				//printf("%s\r\n",TxetBuf);
				if(ESP8266_IpSend((char *)TxetBuf, strlen((char *)TxetBuf)) < 0)
				{//发送失败
					printf("发送响应失败!\r\n");
				}
			}
		}
	}
}
#ifndef _CloudReference_h_
#define _CloudReference_h_
//================在CloudReference.h设置WIFI名称和密码以及设备标识和传输密钥
#define WIFI_AP		"xin"//WiFi热点名称
#define WIFI_PWD	"987654321"	//WiFi密码
#define WIFI_AP1		"zhjt_220"//WiFi热点名称
#define WIFI_PWD1	"12345678zhjt"	//WiFi密码
#define SERVER_IP	"120.77.58.34"	//服务器IP地址
#define SERVER_PORT	8600			//服务器端口号

#define MY_DEVICE_ID  "light2018052790"//设备标识
#define MA_SECRET_KEY "1d1c815e2a504ff9abcf6301134f27d3"//传输密钥

#endif /*_CloudReference_h_*/

语音模块

使用xfs5152ce.c和usart3.c极fifo.c文件,主要功能语音识别和文本合成
步骤:

/***************************************************************
  *	Name		:	MAIN.C
  *	Data		:	2019.7.15
  *	Author	:	NIEAOWEI
  *	Note		:	本实验主要是测试语音模块,连续读不卡顿,中断读,
							以及语音识别功能。
****************************************************************/
#include "usart3.h"
#include "delay.h"
#include "fifo.h"
#include "xfs5152ce.h"
#include "usart1.h"

int main(){
	uint8_t data[10];
	uint8_t a;
	delay_init();
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Usart1_Init(115200);
	usart3_init();
	
	delay_ms(1);
	
	printf("start...\r\n");
	
	xfs_voice_start((unsigned char *)"请说出启动指令",XFS_FORMAT_GBK,1);//语音合成播放指定文本 *data 需要合成播放的文本 format 编码格式 wait_finish 是否等待上次合成结束
	xfs_voice_start((unsigned char *)"请说出启动指令",XFS_FORMAT_GBK,1);//语音合成函数,可以播放想要的信息,参数1 要播放的文字 参数2 编码格式 参数3 是否等待上次合成结束,1等待
	xfs_voice_start((unsigned char *)"请说出启动指令",XFS_FORMAT_GBK,1);
	printf("%d,%d\r\n",usart3_rx_fifo.in,usart3_rx_fifo.out);
	
	//*delay_ms(1000);
	if(xfs_recognize(&a, 5000) == 1)
	{
		xfs_voice_start((unsigned char *)"语音识别成功", XFS_FORMAT_GBK, 1);
		sprintf((char *)data,"%d",a);
		xfs_voice_start((unsigned char *)data,XFS_FORMAT_GBK,1);
		xfs_voice_start((unsigned char *)cmd_word_list[a],XFS_FORMAT_GBK,1);
	}else{
		xfs_voice_start((unsigned char *)"语音识别失败",XFS_FORMAT_GBK,1);
	}
	printf("re :%d\r\n",a);
	for(a=0;a<100;a++){
		printf("%x,",usart3_rx_fifo.data[a]);
	}
	printf("%d,%d\r\n",usart3_rx_fifo.in,usart3_rx_fifo.out);
	
	while(1){
		delay_ms(1000);
		printf("runnig...\r\n");
	};
		
}



四、ADC输出

步骤:
1.时钟初始化
2.ADC初始化
3.声明外部变量,获取电压值,通过公式转化成对应的数据值
连线:
温度光照传感器J6,接PB0
ADC_IN1 PA1
ADC_IN4 PA4
ADC_IN5 PA5
ADC_IN6 PA6
ADC_IN7 PA7
ADC_IN8 PB0
ADC_IN9 PB1
ADC_IN10 PC0
ADC_IN11 PC1
ADC_IN12 PC2
ADC_IN13 PC3


#define ADC1_DR_Address    ((uint32_t)0x4001244C)//ADC1外设地址

#define ADCPORT		GPIOB	//定义ADC接口
#define ADC_CH8		GPIO_Pin_0	
#define ADC_CH9		GPIO_Pin_1	
vu16 ADC_DMA_IN5; //ADC数值存放的变量

void ADC_DMA_Init(void){ //DMA初始化设置
	DMA_InitTypeDef DMA_InitStructure;//定义DMA初始化结构体
	DMA_DeInit(DMA1_Channel1);//复位DMA通道1
	DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //定义 DMA通道外设基地址=ADC1_DR_Address
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_DMA_IN5; //定义DMA通道ADC数据存储器(其他函数可直接读此变量即是ADC值)		//修改一:获取ADC数值地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设为源地址
	DMA_InitStructure.DMA_BufferSize = 1;//定义DMA缓冲区大小(根据ADC采集通道数量修改)																				//修改二:获取ADC的通道数
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//当前外设寄存器地址不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//当前存储器地址:Disable不变,Enable递增(用于多通道采集)				//修改三:多道采集用Enable
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度16位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //定义存储器数据宽度16位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA通道操作模式位环形缓冲模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道优先级高
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//禁止DMA通道存储器到存储器传输
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);//初始化DMA通道1
	DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA通道1
}
void ADC_GPIO_Init(void){ //GPIO初始化设置
	GPIO_InitTypeDef  GPIO_InitStructure; 	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);       
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟(用于ADC的数据传送)
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//使能ADC1时钟
    GPIO_InitStructure.GPIO_Pin = ADC_CH8; //选择端口   																									 										//修改四:  设置获取ADC端口的引脚                        
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //选择IO接口工作方式       
	GPIO_Init(ADCPORT, &GPIO_InitStructure);																																									//修改五:ADCPORT修改接口		
}
void ADC_Configuration(void){ //初始化设置
	ADC_InitTypeDef ADC_InitStructure;//定义ADC初始化结构体变量
	ADC_GPIO_Init();//GPIO初始化设置
	ADC_DMA_Init();//DMA初始化设置
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE; //使能扫描
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//ADC转换工作在连续模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//有软件控制转换
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;//顺序进行规则转换的ADC通道的数目(根据ADC采集通道数量修改)														//修改六:通道数
	ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
	//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
	//ADC1,ADC通道x,规则采样顺序值为y,采样时间为28周期		 
	ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_28Cycles5);//ADC1选择信道x,采样顺序y,采样时间n个周期					//修改七:信道要改为对应引脚通道

	ADC_DMACmd(ADC1, ENABLE);// 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)
	ADC_Cmd(ADC1, ENABLE);//使能ADC1
	ADC_ResetCalibration(ADC1); //重置ADC1校准寄存器
	while(ADC_GetResetCalibrationStatus(ADC1));//等待ADC1校准重置完成
	ADC_StartCalibration(ADC1);//开始ADC1校准
	while(ADC_GetCalibrationStatus(ADC1));//等待ADC1校准完成
	ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1软件开始转换
}
#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "usart.h"

#include "adc.h"

extern vu16 ADC_DMA_IN5; //声明外部变量

int main (void){//主程序
	delay_ms(500); //上电时等待其他器件就绪
	RCC_Configuration(); //系统时钟初始化 
	ADC_Configuration(); //ADC初始化设置
	USART1_Init(115200);
	while(1){
		printf("值:%0.3f\r\n",ADC_DMA_IN5*(3.3/4095));//光照公式
		delay_ms(500); //延时
	}
}

用途

温度光照传感器

使用的是 temp_light.c temp_light.h源文件
实验步骤:
1.初始化温度光照
2.使用GetTemp函数获取温度
3.使用GetLight函数获取光照
接线:
温度输出口:PC0
光照输出口:PC1

uint8_t GetTemp(){
	uint16_t temp;
	temp=GetADC_Time(TEMP_CH,10);
	printf("temp adc value:%d\r\n",temp);
	return calculateTemperature(calculateResValue(temp));
}

/***************************************************************
  *	@brief	获取一次光照值,以百分比的形式计算
  *	@param	
  *	@retval	float 光照值
****************************************************************/
//
float GetLight(){
	uint16_t	light;
	light=GetADC_Time(LIGHT_CH,10);
	printf("light adc value:%d\r\n",light);
	return 100-((float)light*1000/4096)*100/1000;
}

#include "usart1.h"
#include "delay.h"
#include <stdio.h>
#include "temp_light.h"

int main(){
	Byte temp[20];
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	Usart1_Init(115200);
	delay_init();
	TEMP_LIGHT_Init();
	printf("runnning...\r\n");
	while(1){
		printf("temp:%d\r\n",GetTemp());
		printf("light:%d\r\n",GetLight());
		delay_ms(1000);
	}
}

五、DAC输出

步骤:
1.设置系统时钟
2.初始化DAC
3.DAC_OutVoltage(float Voltage)设置引脚输出电压值
接线:
DAC输出口
DAC_OUT1–PA4
DAC_OUT2–PA5

void DAC_Configuration(void)
{
  
	GPIO_InitTypeDef GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitType;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );	  //使能PORTA通道时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );	  //使能DAC通道时钟 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;				 // 端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 		 //模拟输入(STM32没有模拟输出模式,这里只好配置为模拟输入)
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
					
	DAC_InitType.DAC_Trigger=DAC_Trigger_None;	//不使用触发功能 TEN1=0
	DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
	DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;	//DAC1输出缓存关闭 BOFF1=1
  DAC_Init(DAC_Channel_1,&DAC_InitType);	 //初始化DAC通道1

	DAC_Cmd(DAC_Channel_1, ENABLE);  //使能DAC1
  
  DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值,默认输出0V

}
void DAC2_Configuration(void)
{
  
	GPIO_InitTypeDef GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitType;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );	  //使能PORTA通道时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );	  //使能DAC通道时钟 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 // 端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 		 //模拟输入(STM32没有模拟输出模式,这里只好配置为模拟输入)
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
					
	DAC_InitType.DAC_Trigger=DAC_Trigger_None;	//不使用触发功能 TEN1=0
	DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
	DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;	//DAC1输出缓存关闭 BOFF1=1
  DAC_Init(DAC_Channel_2,&DAC_InitType);	 //初始化DAC通道2

	DAC_Cmd(DAC_Channel_2, ENABLE);  //使能DAC2
  
  DAC_SetChannel2Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值,默认输出0V

}

//设置通道1输出电压
// Voltage----电压值,取值范围为0~3.3V
void DAC1_OutVoltage(float Voltage)
{
	uint16_t data;
	data=(uint16_t)(Voltage*4095/3.3);//换算为12位整数值
	DAC_SetChannel1Data(DAC_Align_12b_R,data);//12位右对齐数据格式设置DAC值
	DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE); //启动转换
}

void DAC2_OutVoltage(float Voltage)
{
	uint16_t data;
	data=(uint16_t)(Voltage*4095/3.3);//换算为12位整数值
	DAC_SetChannel2Data(DAC_Align_12b_R,data);//12位右对齐数据格式设置DAC值
	DAC_SoftwareTriggerCmd(DAC_Channel_2,ENABLE); //启动转换
}
#include "stm32f10x.h" //STM32
#include "sys.h"
#include "delay.h"
#include "usart.h"

#include "dac.h"


int main (void){
	float voltage=2;
	delay_ms(500); //
	RCC_Configuration(); // 系统时钟初始化
	DAC_Configuration(); //DAC初始化设置
	USART1_Init(115200);
	DAC1_OutVoltage(voltage);
	while(1){
		while(1)
	{
		
		delay_ms(1000);
		
		if (voltage<3.3)
		{voltage+=0.1;}
		else
		{voltage=0;}
		//voltage=3.3;
		DAC1_OutVoltage(voltage);
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
		printf("DAC输入的数字为:%d",(uint16_t)(voltage*4095/3.3));
		printf("DAC输出电压为:%.3f\n",voltage);
	}
	}
}

比赛总结:
熟悉stm32各个引脚的初始化,会各个模块的各种逻辑使用

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Baal Austin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值