MiniSTM32 学习记录

这里我会记录我接下来所使用过的所有代码,弄成一个一个函数、供自己以后复习、贴代码。


1、点亮LED灯(流水灯)

#include "stm32f10x.h"

void delay_ms(int t);
void LED_Init();
int i, j;
int main(void)
{
	LED_Init();
	while(1){
		GPIOA->BSRR = 0x01000000; // 置 0
		delay_ms(500); 
		GPIOA->BSRR = 0x00000100; // 置 1
		
		GPIOD->BSRR = 0x00040000; // 置0
		delay_ms(500);
		GPIOD->BSRR = 0x00000004; // 置 1
	}
}

void LED_Init()
{
	RCC->APB2ENR|=1<<2; //开启PORTA时钟使能
	RCC->APB2ENR|=1<<5; //开启PORTD时钟使能
	
	GPIOA->CRH&=0xFFFFFFF0;
	GPIOA->CRH|=0X00000003;//PA.8 通用推挽输出
	GPIOA->BSRR=0x00000100; // PA.8 置1
	
	GPIOD->CRL&=0xFFFFF0FF;
	GPIOD->CRL|=0X00000300;//PD.2 通用推挽输出
	GPIOD->BSRR=0x00000004; // PD.2 置1
}
	

void delay_ms(int t) // 啥也不干就是浪费时间
{
	for(i = 0; i < t; i++){
		for(j = 0; j < 1000; j++){
		}
	}
}


2、通过调用库函数实现LED流水灯

#include "stm32f10x.h"

void delay_ms(int t);
void LED_Init();
void RCC_Configuration(void);
int i, j;
int main(void)
{
	LED_Init();
	while(1){
		GPIO_SetBits(GPIOA,GPIO_Pin_8); // PA.8 
		delay_ms(500);
		GPIO_ResetBits(GPIOA,GPIO_Pin_8);
		
		GPIO_SetBits(GPIOD,GPIO_Pin_2); // PD.2
		delay_ms(500);
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);
	}
}

void LED_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure; // 声明GPIO初始化结构变量
	RCC_Configuration();  // 配置时钟
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // IO口配置为推挽输出口
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 频率为50HZ
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // 配置管脚8
	GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化PA8口
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // 配置管脚2
	GPIO_Init(GPIOD, &GPIO_InitStructure); // 初始化PD2口
}
	
void RCC_Configuration(void)
{
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // 使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); // 使能GPIOD时钟
}

void delay_ms(int t)  // for循环浪费时间的延时
{
	for(i = 0; i < t; i++){
		for(j = 0; j < 1000; j++){
		}
	}
}
	


3、实验内容(点一个键、一个灯闪烁两下,另一个灯闪烁一下,反之亦然)

#include "stm32f10x.h"

#define KEY_ON  0
#define KEY_OFF 1

void delay_ms(int t);
void Init();
void GPIO_Configuration(void);
uint8_t KeyScan( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin_x );

int i, j;

char flag = 0;

int main(void)
{
	Init();
	while(1){
		if(KeyScan( GPIOC, GPIO_Pin_5 ) == KEY_ON)//  按下 key0 时 (PC.5)
		{
			flag = 0;
		}else if(KeyScan( GPIOA, GPIO_Pin_15 ) == KEY_ON) // 按下 key1时 (PA.15)
		{
			flag = 1;
		}
		
		if(flag)
		{
			GPIO_SetBits(GPIOA,GPIO_Pin_8); // PA.8 灭,
			GPIO_ResetBits(GPIOD,GPIO_Pin_2); // PD.2 亮
			delay_ms(500);
			GPIO_SetBits(GPIOD,GPIO_Pin_2); // PD.2
			delay_ms(500);
			GPIO_ResetBits(GPIOD,GPIO_Pin_2); // PD.2
			
			delay_ms(500);
			GPIO_ResetBits(GPIOA,GPIO_Pin_8); // PA.8
			GPIO_SetBits(GPIOD,GPIO_Pin_2); // PD.2
			delay_ms(500);			
		}
		else
		{
			GPIO_SetBits(GPIOD,GPIO_Pin_2); // PD.2
			GPIO_ResetBits(GPIOA,GPIO_Pin_8); // PA.8
			delay_ms(500);
			GPIO_SetBits(GPIOA,GPIO_Pin_8); // PA.8 
			delay_ms(500);
			GPIO_ResetBits(GPIOA,GPIO_Pin_8); // PA.8
			
			delay_ms(500);
			GPIO_ResetBits(GPIOD,GPIO_Pin_2); // PD.2
			GPIO_SetBits(GPIOA,GPIO_Pin_8); // PA.8 
			delay_ms(500);
		}
	}
}

void Init()
{
	GPIO_InitTypeDef GPIO_InitStructure; // 声明GPIO结构变量
	GPIO_Configuration();  // 配置时钟,(下面的函数)
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // IO 推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 频率50HZ
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // 配置管脚8
	GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化PA8口
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // 配置管脚2
	GPIO_Init(GPIOD, &GPIO_InitStructure); // 初始化PD2口
	
	GPIO_SetBits(GPIOA,GPIO_InitStructure.GPIO_Pin);
	GPIO_SetBits(GPIOD,GPIO_InitStructure.GPIO_Pin);  // 灯都关闭
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  // 配置管脚5
	GPIO_Init(GPIOC, &GPIO_InitStructure);  // 初始化PC.5口
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; // 配置管脚15
	GPIO_Init(GPIOA, &GPIO_InitStructure);  // 初始化PA.15口
}
	
void GPIO_Configuration(void)
{
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // 使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); // 使能GPIOD时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); // 使能GPIOC时钟
}

void delay_ms(int t)  // for 循环延时
{
	for(i = 0; i < t; i++){
		for(j = 0; j < 1000; j++){
		}
	}
}

static void KeyDelay( uint32_t nCounter ) // 延时 函数
{
    while ( nCounter-- );
}

uint8_t KeyScan( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin_x )
{
    if ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON ) // 检测是否有按键按下
    {
        KeyDelay(0x57E40); // 延时消抖
        if ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON )
        {
            while ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON );  // 等待按键释放
            return KEY_ON;
        }
        else
        {
            return KEY_OFF;
        }
    }
    return KEY_OFF;
}

	

4、3的通过寄存器控制完成(延时消抖没有添加)(感谢老师(╯﹏╰))

#include "stm32f10x.h"  
  
void delay_ms(int t);  
void Init();  
void GPIO_Configuration(void);  
  
int i, j;  
  
char flag = 0;  // 标记  
  
int main(void)  
{  
    Init();  
    while(1){  
        if(~GPIOC->IDR & 1 << 5)  // 按下 key1  (PA15)  
        {  
            flag = 0;  
        }else if(~GPIOA->IDR & 1 << 15) // 按下0 (PC5)  
        {  
            flag = 1;  
        }  
          
        if(flag)  
        {  
            GPIOA->BSRR = 0x01000000; // 置 0  
	    delay_ms(500);   
	    GPIOA->BSRR = 0x00000100; // 置 1  
	    delay_ms(500);   
	    GPIOA->BSRR = 0x01000000; // 置 0  
	    delay_ms(500);   
					
	    GPIOA->BSRR = 0x00000100; // 置 1  
	    GPIOD->BSRR = 0x00040000; // 置 0  
	    delay_ms(500);  
	    GPIOD->BSRR = 0x00000004; // 置 1  
        }else  
        {  
	    GPIOD->BSRR = 0x00040000; // 置 0  
	    delay_ms(500);  
	    GPIOD->BSRR = 0x00000004; // 置 1 
	    delay_ms(500);  
	    GPIOD->BSRR = 0x00040000; // 置 0 
	    delay_ms(500);  
					
	    GPIOD->BSRR = 0x00000004; // 置 1
	    GPIOA->BSRR = 0x01000000; // 置 0  
	    delay_ms(500);   
	    GPIOA->BSRR = 0x00000100; // 置 1 
        }  
    }  
}  
  
void Init()  
{  
    RCC->APB2ENR|=1<<2; //使能PORTA时钟  
    RCC->APB2ENR|=1<<4; //使能PORTC时钟
    RCC->APB2ENR|=1<<5; //使能PORTD时钟   
	
    GPIOA->CRH&=0xFFFFFFF0;  
    GPIOA->CRH|=0X00000003;//PA.8 推挽输出  
    GPIOA->BSRR=0x00000100; // PA.8 置1  
    
    GPIOD->CRL&=0xFFFFF0FF;  
    GPIOD->CRL|=0X00000300;//PD.2 推挽输出  
    GPIOD->BSRR=0x00000004; // PD.2 置1  
	
    GPIOC->CRL&=0XFFF0FFFF; 
    GPIOC->CRL|=0X00040000;//PC.5 浮空输入
		
    GPIOA->CRH&=0x0FFFFFFF;  
    GPIOA->CRH|=0X40000000;//PA.15 浮空输入 
}  
      
void GPIO_Configuration(void)  
{  
    SystemInit();  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // 使能GPIOA时钟 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); // 使能GPIOD时钟 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); // 使能GPIOC时钟  
}  
  
void delay_ms(int t)  // 延时
{  
    for(i = 0; i < t; i++){  
        for(j = 0; j < 1000; j++){  
        }  
    }  
}  
  
      


5、静态数码管:

#include"stm32f10x.h"

unsigned char LED7Code[] =
								{~0x3F,~0x06,~0x5B,~0x4F,
								~0x66,~0x6D,~0x7D,~0x07,
								~0x7F,~0x6F,~0x77,~0x7C,
								~0x39,~0x5E,~0x79,~0x71,
								}; // 0 -> 9 只需要9个
u8 Count = 0;
void RCC_Configuration(void);
void delay_nms(u16 time);

int main(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_Configuration();
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 设置为推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 工作频率
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
	GPIO_Init(GPIOB, &GPIO_InitStructure); // 给 GPIOB 赋予上述属性
	GPIO_SetBits(GPIOB,GPIO_InitStructure.GPIO_Pin); // 打开这些管脚

	while(1)
	{
		Count++;
		GPIO_Write(GPIOB,LED7Code[Count%10]<<8); // 0 -> 9 循环
		delay_nms(500);
	}
}

void RCC_Configuration(void)
{
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); // 使能时钟、
}

void delay_nms(u16 time)
{
	u16 i=0;
	while(time--)
	{
		i=12000;
		while(i--);
	}
}


6、动态数码管:(*^__^*) 谢谢大家的关注,

#include"stm32f10x.h"
#define LS138A GPIO_Pin_5  // 宏
#define LS138B GPIO_Pin_6
#define LS138C GPIO_Pin_7
 
#define LS138a(x) x ? GPIO_SetBits(GPIOB, LS138A):GPIO_ResetBits(GPIOB, LS138A)  //  x为1否?1 执行前面的,0,执行后面的
#define LS138b(x) x ? GPIO_SetBits(GPIOB, LS138B):GPIO_ResetBits(GPIOB, LS138B)
#define LS138c(x) x ? GPIO_SetBits(GPIOB, LS138C):GPIO_ResetBits(GPIOB, LS138C)
 
u8 Count;
u16 Count0;
unsigned long D[16], LedOut[8];
unsigned char Disp_Tab[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40}; // 数码管显示、
 
void RCC_Configuration(void);
void GPIO_Configuration(void);
void delay_nms(u16 time);
 
int main(void)
{
	RCC_Configuration();
	GPIO_Configuration();
	while(1)
	{
		unsigned char i;
		Count++;
		if(Count==100)
		{
			Count0++;
			Count=0;
		}
		D[1] = D[0] = Count0;
		LedOut[0] = Disp_Tab[D[1]%10000/1000]; // 千
		LedOut[1] = Disp_Tab[D[1]%1000/100]; // 百
		LedOut[2] = Disp_Tab[D[1]%100/10]|0x80; // 十
		LedOut[3] = Disp_Tab[D[1]%10]; // 个

		LedOut[4] = Disp_Tab[D[0]%10000/1000]; // 千
		LedOut[5] = Disp_Tab[D[0]%1000/100]; // 百
		LedOut[6] = Disp_Tab[D[0]%100/10]|0x80; // 十
		LedOut[7] = Disp_Tab[D[0]%10]; // 个
		for(i=0; i<8; i++)
		{
			GPIO_Write(GPIOB, LedOut[i]<<8);  // 位操作 <<8(低八位->高八位)
			switch(i) // 1,3,8 译码器
			{
				case 0: LS138c(0); LS138b(0); LS138a(0); break; // 0 0 0
				case 1: LS138c(0); LS138b(0); LS138a(1); break; // 1 0 0
				case 2: LS138c(0); LS138b(1); LS138a(0); break; // 0 1 0
				case 3: LS138c(0); LS138b(1); LS138a(1); break; // 1 1 0
				case 4: LS138c(1); LS138b(0); LS138a(0); break; // 0 0 1
				case 5: LS138c(1); LS138b(0); LS138a(1); break; // 1 0 1
				case 6: LS138c(1); LS138b(1); LS138a(0); break; // 0 1 1
				case 7: LS138c(1); LS138b(1); LS138a(1); break; // 1 1 1
			}
			delay_nms(1);
		}
	}
}
 
void RCC_Configuration(void)
{
	SystemInit(); // 72HMHZ
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  // 使能GPIOB时钟
}
 
void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
	GPIO_Init(GPIOB,&GPIO_InitStructure); //给 GPIOB 赋予上述属性(8 -> 15)
	 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;  //  管脚5,,6,7
	GPIO_Init(GPIOB,&GPIO_InitStructure); // 再次给GPIOB赋予上述属性(5,6,7)
	 
	GPIO_SetBits(GPIOB,GPIO_InitStructure.GPIO_Pin); // 置位
}
 
void delay_nms(u16 time)
{
	u16 i=0;
	while(time--)
	{
		i=1000;
		while(i--);
	}
}

7、4*4矩阵键盘

#include "stm32f10x.h"

#define uchar unsigned char 
#define uint unsigned int
	
int keyscan();
void delay_nms(u16 time);
void GPIO_Configuration(void);

unsigned char LED7Code[] = {~0x3F, ~0x06, ~0x5B, ~0x4F,
							~0x66, ~0x6D, ~0x7D, ~0x07,
							~0x7F, ~0x6F, ~0x77, ~0x7C,
							~0x39, ~0x5E, ~0x79, ~0x71}; // 0 - F 的数码管显示

int x; 
uchar temp;
uchar key;
u16 ReadedData;

int main(void)
{
	GPIO_Configuration();
	
	while(1)
	{
		x = keyscan();
		if(x >= 0)
		{
			GPIO_Write(GPIOA, LED7Code[x] << 8);
		}
	}	
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; // 声明GPIO初始化结构变量、
	
	// 使能APB2总线外设时钟、
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 开启PB时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 开启PA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 开启复用IO时钟
	
	// ↓ PB3和PB4被用在JTAG接口中,把这两个管脚释放出来,作为普通IO口
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);

	GPIO_InitStructure.GPIO_Pin = 
	                GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | 
	                GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 输出模式下 i/0输出的速度
	GPIO_Init(GPIOA, &GPIO_InitStructure); // PA口初始化
	
	GPIO_Write(GPIOA, LED7Code[8] << 8); // 七段数码管全部点亮、
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | 
				              GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // I/O口输出速度
	GPIO_Init(GPIOB, &GPIO_InitStructure); // PB口初始化
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | 
	       			              GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
}


int keyscan()
{
	temp = 0;
	
	GPIO_Write(GPIOB, 0xFFF0); // PB3-PB0 输出低电平
	
	if((GPIOB->IDR & 0x00F0) == 0x00F0) // PB7-PB4全为1,表明没有按键按下,返回-1
	{
		return -1;
	}
	else
	{
		delay_nms(5); // 延时去抖
		if((GPIOB->IDR & 0x00F0) == 0x00F0) // 抖动产生的、
		{
			return -1;
		}
	}
	
	GPIO_Write(GPIOB, 0xFFFE); // PB3 = PB2 = PB1 = 1、PB0 = 0
	temp = ~(GPIOB->IDR | 0xFF0F);
	switch(temp) // 对PB7-PB4的值进行判断,
	{
		case 0x0010 : key = 0; break;
		case 0x0020 : key = 1; break;
		case 0x0040 : key = 2; break;
		case 0x0080 : key = 3; break;
	}
	
	GPIO_Write(GPIOB, 0xFFFD); // PB2 = 0,PB0 = PB1 = PB3 = 1
	temp = ~(GPIOB->IDR | 0xFF0F);
	switch(temp) // 对PB7-PB4的值进行判断,
	{
		case 0x0010 : key = 4; break;
		case 0x0020 : key = 5; break;
		case 0x0040 : key = 6; break;
		case 0x0080 : key = 7; break;
	}
	
	GPIO_Write(GPIOB, 0xFFFB); // PB3 = PB 1 = PB0 = 1, PB2 = 0
	temp = ~(GPIOB->IDR | 0xFF0F);
	switch(temp)
	{
		case 0x0010 : key = 8; break;
		case 0x0020 : key = 9; break;
		case 0x0040 : key = 10; break;
		case 0x0080 : key = 11; break;
	}
	
	
	GPIO_Write(GPIOB, 0xFFF7); // PB3 = 0, PB2 = PB1 = PB0 = 1, 
	temp = ~(GPIOB->IDR | 0xFF0F);
	switch(temp)
	{
		case 0x0010 : key = 12; break;
		case 0x0020 : key = 13; break;
		case 0x0040 : key = 14; break;
		case 0x0080 : key = 15; break;
	}
	return key;
	
}

void delay_nms(u16 time)
{
	u16 i = 0;
	while(time--)
	{
		i = 12000;
		while(i--);
	}
}

8、lcd显示

lcd_1602.h

/* LCD1602.h*/

#ifndef __LCD1602_H
#define __LCD1602_H

#define uchar unsigned char
#define uint unsigned int
#define uint unsigned int
	
void delay(uint a); //延时函数,空循环函数
void delay_ms(uint time); //毫秒级延时
void delay_us(uint time); //微秒级延时
void enable(uchar del); //使能LCD,按时序的底层驱动
void write(uchar del); //写LCD,按时序的底层驱动
void L1602_init(void); //1602初始化
void L1602_char(uchar row, uchar column,char sign); //按行列位置写字符
void L1602_string(uchar row, uchar column,char *p); //从行列位置写字符串

void L1602_Clear(void); //清屏
void L1602_DispNum(uchar row, uchar column, uint num);
void L1602_DispFloatNum(uchar row, uchar column, double num);
#endif

lcd.c代码:

#include "stm32f10x.h"
#include "lcd_1602.h"


void RCC_Configuration(void);
void Port_Init(void);
int main(void)
{
	RCC_Configuration();
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE); //禁用SDJ和JTAG,释放口线用作IO输出
	Port_Init();
	L1602_init();

	while (1)
	{
		L1602_Clear();
		L1602_string(1,1,"Hello, World!");
		L1602_string(2,1,"I can do that ");
		delay(1000);

		L1602_Clear();
		L1602_string(1,1,"Integer:"); 
		L1602_DispNum(2,1,100);  //显示整数数字
		L1602_string(2,5,"V.");
		delay(1000);
		
		L1602_Clear();
		L1602_string(1,1,"Float:"); 
		L1602_DispFloatNum(2,1,123.898); //显示浮点数
		L1602_string(2,8,"V.");
		delay(1000);
	}
	
}

void RCC_Configuration(void) //配置系统时钟
{ 
	SystemInit();//72MHz
	//下面给各模块开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|
				RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	//TIM2时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
}

void Port_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; //声明GPIO初始化结构变量
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;  // 管脚PB0、1、2
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //推挽输出
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 
	GPIO_Init(GPIOB,&GPIO_InitStructure); 
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|
				    GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|
				    GPIO_Pin_14|GPIO_Pin_15; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 
	GPIO_Init(GPIOB,&GPIO_InitStructure); 
	
	delay(100);
}

lcd_1602.c:

#include "lcd_1602.h"
#include "stm32f10x_gpio.h"
#include "stdio.h"

#define lcm_ce_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_0) // E-----LCD-Pin6 -----STM32-PB0
#define lcm_ce_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_0)

#define lcm_rst_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_1) // RS----LCD-Pin4-----STM32-PB1
#define lcm_rst_HIGH()		        GPIO_SetBits(GPIOB, GPIO_Pin_1)


#define lcm_wr_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_2) // WR----LCD-Pin5-----STM32-PB2
#define lcm_wr_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_2)


#define DATA_0_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_8)  //置0
#define DATA_0_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_8)   // 置1

#define DATA_1_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_9)
#define DATA_1_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_9) 

#define DATA_2_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_10)
#define DATA_2_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_10) 

#define DATA_3_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_11)
#define DATA_3_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_11) 

#define DATA_4_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define DATA_4_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_12) 

#define DATA_5_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_13)
#define DATA_5_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_13) 

#define DATA_6_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_14)
#define DATA_6_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_14) 

#define DATA_7_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_15)
#define DATA_7_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_15) 

void DATA(unsigned int d)
{
	if (d&0x01) {DATA_0_HIGH();}	else {DATA_0_LOW();}
	if (d&0x02) {DATA_1_HIGH();}	else {DATA_1_LOW();}
	if (d&0x04) {DATA_2_HIGH();}	else {DATA_2_LOW();}
	if (d&0x08) {DATA_3_HIGH();}	else {DATA_3_LOW();}
	if (d&0x10) {DATA_4_HIGH();}	else {DATA_4_LOW();}
	if (d&0x20) {DATA_5_HIGH();}	else {DATA_5_LOW();}
	if (d&0x40) {DATA_6_HIGH();}	else {DATA_6_LOW();}
	if (d&0x80) {DATA_7_HIGH();}	else {DATA_7_LOW();}
}

void E(unsigned char i) //使能LCD
{
	if(i) {lcm_ce_HIGH();} else {lcm_ce_LOW();}
}

void RS(unsigned char i) // 开 RS(0关,!0开)
{
	if(i) {lcm_rst_HIGH();} else {lcm_rst_LOW();}
}

void RW(unsigned char i) // 开RW(0关,!0开)
{
	if(i) {lcm_wr_HIGH();} else {lcm_wr_LOW();}
}

void delay(uint a) 
{
u16 i=0;  
	while(a--)
	{	i=12000;  
		while(i--) ;    
	}
}

void delay_us(uint time)
{ u16 i=0;  
	while(time--)
	{	i=10;  
		while(i--) ;    
	}
}


void delay_ms(uint time) 
{	u16 i=0;  
	while(time--)
	{	i=12000;  
		while(i--) ;    
	}
}

void enable(uchar del)
{
	DATA(del);
	RS(0); 
	RW(0); 
	E(0);  
	delay_ms(10);
	E(1); 
	delay_ms(10);
	E(0); 
	
}

void write(uchar del) 
{
	DATA(del);
	RS(1); 
	RW(0); 
	E(0); 
	delay_ms(10);
	E(1); 
	delay_ms(10);
	E(0); 
}

void L1602_init(void)//1602???,
{
	delay_ms(10);
	enable(0x38); 
	delay_ms(10);
	enable(0x06);
	delay_ms(10);
	enable(0x0C); 
	delay_ms(10);
	enable(0x01);	
	delay_ms(10);
}

void L1602_Clear(void) //1602清屏,
{
	delay_ms(10);
	enable(0x01);
	delay_ms(10);
}

void L1602_char(uchar row, uchar column,char sign) 
{
	uchar a;
	if (row==1) a=0x80;
	if (row==2) a=0xc0;
	a = a + column - 1;
	enable(a);
	write(sign);
}

void L1602_string(uchar row, uchar column,char *p) 
{
	uchar a;
	if (row==1) a=0x80;
	if (row==2) a=0xc0;
	a = a + column - 1;
	enable(a);
	while(*p!='\0') 
	{
		write(*p);
		p++;
	}
	/*while(1)
	{
		if (*p==';') break; 
		write(*p);
		p++;
	}*/
}


void L1602_DispNum(uchar row, uchar column, uint num) 
{
/*	
	uint i=0,j,k=0,wei,q;
	char str[32];
	if(num>=10000000)wei=8; 
	else if(num>=1000000)wei=7;
	else if(num>=100000)wei=6;
	else if(num>=10000)wei=5;
	else if(num>=1000) wei=4;
	else if(num>=100)wei=3;
	else if(num>=10) wei=2;
	else wei=1;
	

	for(i=wei;i>0;i--) 
	{ 
		q=1;
		j=1; 
		for(;j<i;j++)
		{
			q *=10; //10*q
		}
		str[k++]=num/q +'0';
		num %= q; 
	}
	str[k] = '\0'; 
	*/
	
	char str[32];
	sprintf(str,"%d", num ); // num中存储数据的格式化写入str中
		
	L1602_string(row, column, str); // 在lcd的row行,column列写入str
}

void L1602_DispFloatNum(uchar row, uchar column, double num)
{
	char str[32];
        sprintf(str,"%.2f", num );  // num中存储的数据格式化写入str中
	L1602_string(row, column, str); // 在lcd显示屏的row行,colunm列写str
}




9、LCD结合矩阵键盘输入

lcd_1602.h

/* LCD1602.h*/

#ifndef __LCD1602_H
#define __LCD1602_H

#define uchar unsigned char
#define uint unsigned int
#define uint unsigned int
	

keyboard.h

int keyscan(void);
void delay_nms(u16 time);
void GPIO_Configuration(void);

keyboard.c

#include "stm32f10x.h"

#define uchar unsigned char 
#define uint unsigned int
	
int keyscan();
void delay_nms(u16 time);
void GPIO_Configuration(void);

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure; // 声明GPIO初始化结构变量
	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 开启PB时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 开始PB时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 开启复用IO时钟
	
	// ↓ PB3,PB4被用在JTAG接口中,把这两个管脚释放出来,作为普通的IO口
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | 
					GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure); // PA口初始化
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | 
				        GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
}


int keyscan(void)
{
	uchar temp;
	uchar key;
	
	temp = 0;
	
	GPIO_Write(GPIOA, 0xFFF0); // PB3-PB0 输出低电平
	
	if((GPIOA->IDR & 0x00F0) == 0x00F0) // PB7-PB4全为1,没有按键按下
	{
		return -1;
	}
	else
	{
		delay_nms(5); // 延时去抖
		if((GPIOA->IDR & 0x00F0) == 0x00F0) // 抖动产生
		{
			return -1;
		}
	}
	
	GPIO_Write(GPIOA, 0xFFFE); // PB3 = PB2 = PB1 = 1?PB0 = 0
	temp = ~(GPIOA->IDR | 0xFF0F);
	switch(temp) // 对PB7-PB4的值进行判断,
	{
		case 0x0010 : key = 0; break;
		case 0x0020 : key = 1; break;
		case 0x0040 : key = 2; break;
		case 0x0080 : key = 3; break;
	}
	
	GPIO_Write(GPIOA, 0xFFFD); // PB2 = 0,PB0 = PB1 = PB3 = 1
	temp = ~(GPIOA->IDR | 0xFF0F);
	switch(temp) 
	{
		case 0x0010 : key = 4; break;
		case 0x0020 : key = 5; break;
		case 0x0040 : key = 6; break;
		case 0x0080 : key = 7; break;
	}
	
	GPIO_Write(GPIOA, 0xFFFB); // PB3 = PB 1 = PB0 = 1, PB2 = 0
	temp = ~(GPIOA->IDR | 0xFF0F);
	switch(temp)
	{
		case 0x0010 : key = 8; break;
		case 0x0020 : key = 9; break;
		case 0x0040 : key = 10; break;
		case 0x0080 : key = 11; break;
	}
	
	
	GPIO_Write(GPIOA, 0xFFF7); // PB3 = 0, PB2 = PB1 = PB0 = 1, 
	temp = ~(GPIOA->IDR | 0xFF0F);
	switch(temp)
	{
		case 0x0010 : key = 12; break;
		case 0x0020 : key = 13; break;
		case 0x0040 : key = 14; break;
		case 0x0080 : key = 15; break;
	}
	return key;
	
}

void delay_nms(u16 time)
{
	u16 i = 0;
	while(time--)
	{
		i = 12000;
		while(i--);
	}
}

lcd_1602.c

#include "lcd_1602.h"
#include "stm32f10x_gpio.h"
#include "stdio.h"

#define lcm_ce_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_0) // E-----LCD-Pin6 -----STM32-PB0
#define lcm_ce_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_0)

#define lcm_rst_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_1) // RS----LCD-Pin4-----STM32-PB1
#define lcm_rst_HIGH()		GPIO_SetBits(GPIOB, GPIO_Pin_1)


#define lcm_wr_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_2) // WR----LCD-Pin5-----STM32-PB2
#define lcm_wr_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_2)


#define DATA_0_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_8)  //复位总线第0位
#define DATA_0_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_8)   // 置数据总线第0位

#define DATA_1_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_9)
#define DATA_1_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_9) 

#define DATA_2_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_10)
#define DATA_2_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_10) 

#define DATA_3_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_11)
#define DATA_3_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_11) 

#define DATA_4_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define DATA_4_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_12) 

#define DATA_5_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_13)
#define DATA_5_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_13) 

#define DATA_6_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_14)
#define DATA_6_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_14) 

#define DATA_7_LOW()			GPIO_ResetBits(GPIOB, GPIO_Pin_15)
#define DATA_7_HIGH()			GPIO_SetBits(GPIOB, GPIO_Pin_15) 

void DATA(unsigned int d) // 根据数据d的8位二进制来确定对数据总线上哪一位置位或清零
{
	if (d&0x01) {DATA_0_HIGH();}	else {DATA_0_LOW();}
	if (d&0x02) {DATA_1_HIGH();}	else {DATA_1_LOW();}
	if (d&0x04) {DATA_2_HIGH();}	else {DATA_2_LOW();}
	if (d&0x08) {DATA_3_HIGH();}	else {DATA_3_LOW();}
	if (d&0x10) {DATA_4_HIGH();}	else {DATA_4_LOW();}
	if (d&0x20) {DATA_5_HIGH();}	else {DATA_5_LOW();}
	if (d&0x40) {DATA_6_HIGH();}	else {DATA_6_LOW();}
	if (d&0x80) {DATA_7_HIGH();}	else {DATA_7_LOW();}
}

void E(unsigned char i) //使能LCD
{
	if(i) {lcm_ce_HIGH();} else {lcm_ce_LOW();}
}

void RS(unsigned char i) // 根据参数i,确定是置位RS,还是清零RS
{
	if(i) {lcm_rst_HIGH();} else {lcm_rst_LOW();}
}

void RW(unsigned char i) // 根据参数i,确定是置位RW,还是清零RW
{
	if(i) {lcm_wr_HIGH();} else {lcm_wr_LOW();}
}

void delay(uint a) 
{
    u16 i=0;  
	while(a--)
	{	i=12000;  
		while(i--) ;    
	}
}

void delay_us(uint time)
{ u16 i=0;  
	while(time--)
	{	i=10;  
		while(i--) ;    
	}
}


void delay_ms(uint time) 
{	u16 i=0;  
	while(time--)
	{	i=12000;  
		while(i--) ;    
	}
}

void enable(uchar del) // 1602命令函数,输入的命令值,根据时序来使能LCD
{
	DATA(del); // 根据命令集,按照时序来使能LCD
	RS(0);  // RS = 0,选择写指令寄存器, RS = 1 选择写数据寄存器
	RW(0);  // RW = 0, 进行写操作, RW = 1 进行读操作
	E(0);  // E 使能位
	delay_ms(10);
	E(1);  // 使能
	delay_ms(10);
	E(0); 
	
}

void write(uchar del)  // 1602写数据函数,输入的是需要写入1602的数据
{
	DATA(del);
	RS(1); 
	RW(0); 
	E(0); 
	delay_ms(10);
	E(1); 
	delay_ms(10);
	E(0); 
}

void L1602_init(void) //1602初始化
{
	delay_ms(10);
	enable(0x38);  // 设置16 * 2显示, 5 * 7点阵,8位数据接口
	delay_ms(10);
	enable(0x06); // 地址+1,当写入数据,光标右移
	delay_ms(10);
	enable(0x0C);  // 开显示,不显示光标
	delay_ms(10);
	enable(0x01);	 // 清屏
	delay_ms(10);
}

void L1602_Clear(void) //1602清屏,
{
	delay_ms(10);
	enable(0x01); // 清屏
	delay_ms(10);
}

void L1602_char(uchar row, uchar column,char sign) // 按行列位置写字符
{
	uchar a;
	if (row==1) a=0x80; // 在第一行显示
	if (row==2) a=0xc0; // 在第二行显示
	a = a + column - 1; // 计算要显示字符的位置
	enable(a);
	write(sign); // 写字符sign
}

void L1602_string(uchar row, uchar column,char *p) // 从行列位置写字符串
{
	uchar a;
	if (row==1) a=0x80; // 在第一行显示
	if (row==2) a=0xc0; // 在第二行显示
	a = a + column - 1; // 计算要显示字符串的位置
	enable(a);
	while(*p!='\0')  // 一直写(没有到末尾)
	{
		write(*p); // 写进去(字符)
		p++;
	}
	/*while(1)
	{
		if (*p==';') break; 
		write(*p);
		p++;
	}*/
}


void L1602_DispNum(uchar row, uchar column, uint num)  // 写入整数
{
	char str[32];
	sprintf(str,"%d", num ); // 将 num(整数),转化为字符串
		
	L1602_string(row, column, str); // 写
}

void L1602_DispFloatNum(uchar row, uchar column, double num) // 写入浮点数
{
	char str[32];
  sprintf(str,"%.2f", num );  // 将浮点数转化为字符串(保留两位小数)
	L1602_string(row, column, str); // 写
}




lcd.c

#include "stm32f10x.h"
#include "lcd_1602.h"
#include "keyboard.h"

void RCC_Configuration(void);
void Port_Init(void);

int x; 
uchar temp;
uchar key;
u16 ReadedData;

int main(void)
{
	GPIO_Configuration();
	RCC_Configuration();
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);//禁用SDJ和JTAG,释放口线用作IO输出
	Port_Init();
	L1602_init();
	
	while (1)
	{
		L1602_Clear();
		L1602_string(1,1,"input is Integer!"); //先显示一行,(提示输入)
		x = keyscan(); // 获取输入的信息
		if(x == -1) // 没有输入就等待
		{
				while(x == -1)
				{
					x = keyscan();
				}
		}
		L1602_DispNum(2,1,x); //将得到的x写入
		L1602_string(2,5,"xixi");
		delay(1000);
		L1602_Clear();
		
	}
	
}

void RCC_Configuration(void) //配置系统时钟
{ 
	SystemInit();//72MHz
	//开启各时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	//TIM2时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
}

void Port_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构体变量
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 
	GPIO_Init(GPIOB,&GPIO_InitStructure); // 初始化管脚
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9|
				    GPIO_Pin_10|GPIO_Pin_11|
				    GPIO_Pin_12|GPIO_Pin_13|
				    GPIO_Pin_14|GPIO_Pin_15; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; 
	GPIO_Init(GPIOB,&GPIO_InitStructure); 
	
	delay(100);
}


连线:



10、TFT LCD实验(显示图片)

image2lcd.c

#include "sys.h"
#include "lcd.h"
#include "image2lcd.h"

//从8位数据获得16位颜色
//mode:0,低位在前,高位在后.
//     1,高位在前,低位在后.
//str:数据
u16 image_getcolor(u8 mode,u8 *str)
{
	u16 color;
	if(mode)
	{
		color=((u16)*str++)<<8;
		color|=*str;
	}else
	{
		color=*str++;
		color|=((u16)*str)<<8;
	}
	return color;	
}
//在液晶上画图
//xsta,ysta,xend,yend:画图区域
//scan:见image2lcd V2.9的说明.
//*p:图像数据
void image_show(u16 xsta,u16 ysta,u16 xend,u16 yend,u8 scan,u8 *p)
{  
	u32 i;
	u32 len=0;
	LCD_Set_Window(xsta,ysta,xend,yend);
	if((scan&0x03)==0)//水平扫描
	{
		switch(scan>>6)//设置扫描方式
		{
			case 0:
				LCD_Scan_Dir(L2R_U2D);//从左到右,从上到下
				LCD_SetCursor(xsta,ysta);//设置光标位置 
				break; 
			case 1:
				LCD_Scan_Dir(L2R_D2U);//从左到右,从下到上
				LCD_SetCursor(xsta,yend);//设置光标位置 
				break; 
			case 2:
				LCD_Scan_Dir(R2L_U2D);//从右到左,从上到下
				LCD_SetCursor(xend,ysta);//设置光标位置 
				break; 
			case 3:
				LCD_Scan_Dir(R2L_D2U);//从右到左,从下到上
				LCD_SetCursor(xend,yend);//设置光标位置 
				break; 
		}
	}else  //垂直扫描
	{
		switch(scan>>6)//设置扫描方式
		{
			case 0:
				LCD_Scan_Dir(U2D_L2R);//从上到下,从左到右
				LCD_SetCursor(xsta,ysta);//设置光标位置 
				break; 
			case 1:
				LCD_Scan_Dir(D2U_L2R);//从下到上从,左到右
				LCD_SetCursor(xsta,yend);//设置光标位置 
				break; 
			case 2:
				LCD_Scan_Dir(U2D_R2L);//从上到下,从右到左 
				LCD_SetCursor(xend,ysta);//设置光标位置 
				break; 
			case 3:
				LCD_Scan_Dir(D2U_R2L);//从下到上,从右到左
				LCD_SetCursor(xend,yend);//设置光标位置 
				break; 
		}
	}
	LCD_WriteRAM_Prepare();     		//开始写入GRAM
	len=(xend-xsta+1)*(yend-ysta+1);	//写入的数据长度
	for(i=0;i<len;i++)
	{
		LCD_WR_DATA(image_getcolor(scan&(1<<4),p));
		p+=2;
	} 	 
#if USE_HORIZONTAL  //使用横屏	
	LCD_Set_Window(0,0,319,239);
#else
	LCD_Set_Window(0,0,239,319);
#endif	    					  	    
}  

//在指定的位置显示一个图片
//此函数可以显示image2lcd软件生成的任意16位真彩色图片.
//限制:1,尺寸不能超过屏幕的区域.
//     2,生成数据时不能勾选:高位在前(MSB First)
//     3,必须包含图片信息头数据
//x,y:指定位置
//imgx:图片数据(必须包含图片信息头,"4096色/16位真彩色/18位真彩色/24位真彩色/32位真彩色”的图像数据头)
//注意:针对STM32,不能选择image2lcd的"高位在前(MSB First)"选项,否则imginfo的数据将不正确!!
void image_display(u16 x,u16 y,u8 * imgx)
{
	HEADCOLOR *imginfo;
 	u8 ifosize=sizeof(HEADCOLOR);//得到HEADCOLOR结构体的大小
	imginfo=(HEADCOLOR*)imgx;
 	image_show(x,y,x+imginfo->w-1,y+imginfo->h-1,imginfo->scan,imgx+ifosize);		
}

main.c

#include "stm32f10x.h"
#include "delay.h"
#include "image2lcd.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "led.h"

extern const u8 gImage_zz[];//图片数据(包含信息头),存储在image1.c里面. 需要用Image2Lcd去处理成c语言模式

int main(void)
{		
	
	delay_init();	    	 //延时函数初始化	  
	uart_init(9600);	 	//串口初始化为9600
	LED_Init();		  		//初始化与LED连接的硬件接口
 	LCD_Init();

  HEADCOLOR *imginfo;
	u16 x=0,y=0;
 	imginfo=(HEADCOLOR*)gImage_zz;	//得到文件信息 

	POINT_COLOR=RED;   	
   					 
	delay_ms(1500);//等待1.5秒	  
	srand(imginfo->h*imginfo->w);
	while(1) 
	{		   
			image_display(x,y,(u8*)gImage_zz);//在指定地址显示图片
			LCD_ShowString(130,280,240,12,12,"By QLU_fuchen");			 
			delay_ms(200);	
	}											    
}


对于剩下的代码嘛,导入来导入去的,去正点原子的资料里面找吧    (The code comes from 原子哥)



11、中断(把代码贴贴,以后粘贴过去修改)

#include "stm32f10x.h"

char flag = 0;
void RCC_Configuration(void);
void GPIO_Configuration(void);
void EXTI_Configuration(void);
void NVIC_Configuration(void);
void delay_nms(u16 time);

int main(void)
{
	RCC_Configuration(); // 时钟
	GPIO_Configuration(); // GPIO
	EXTI_Configuration(); // 外部中断
	NVIC_Configuration(); // 向量中断控制器
	
	while(1)
	{
		if (flag)
		{
			GPIO_SetBits(GPIOA,GPIO_Pin_8);
			GPIO_SetBits(GPIOD,GPIO_Pin_2);
			
			GPIO_ResetBits(GPIOA,GPIO_Pin_8);
			delay_nms(500);
			GPIO_SetBits(GPIOA,GPIO_Pin_8);
			delay_nms(500);
			
			GPIO_ResetBits(GPIOA,GPIO_Pin_8);
			delay_nms(500);
			GPIO_SetBits(GPIOA,GPIO_Pin_8);
			delay_nms(500);
			
			GPIO_ResetBits(GPIOD,GPIO_Pin_2);
			delay_nms(500);
			GPIO_SetBits(GPIOD,GPIO_Pin_2);
			delay_nms(500);
		}else{
			GPIO_SetBits(GPIOA,GPIO_Pin_8);
			GPIO_SetBits(GPIOD,GPIO_Pin_2);
			
			GPIO_ResetBits(GPIOD,GPIO_Pin_2);
			delay_nms(500);
			GPIO_SetBits(GPIOD,GPIO_Pin_2);
			delay_nms(500);
			
			GPIO_ResetBits(GPIOD,GPIO_Pin_2);
			delay_nms(500);
			GPIO_SetBits(GPIOD,GPIO_Pin_2);
			delay_nms(500);
			
			GPIO_ResetBits(GPIOA,GPIO_Pin_8);
			delay_nms(500);
			GPIO_SetBits(GPIOA,GPIO_Pin_8);
			delay_nms(500);
		}
	}
}

void RCC_Configuration(void) // 配置时钟
{
	SystemInit(); //72MHz

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // 使能AFIO时钟
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //关掉JTAG,不关SW
	// STM32中PA13、PA14、PA15、PB03PB04是默认的FTAG引脚映射
	// 释放PA15   (PA15默认为JTAG功能,这里为了使用PA15需要首先释放口线)
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure); 
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; 
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOD,&GPIO_InitStructure); 
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; // 上拉输入
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU ; 
	GPIO_Init(GPIOC,&GPIO_InitStructure); 
	
	GPIO_SetBits(GPIOA,GPIO_Pin_8);
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
}

void EXTI_Configuration(void) // 配置外部中断源
{
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line=EXTI_Line15|EXTI_Line5; // 外部中短线Line12 | Line5
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //选择中断模式
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发
	EXTI_InitStructure.EXTI_LineCmd=ENABLE; //使能中断
	EXTI_Init(&EXTI_InitStructure);  // 初始化外部中断
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15); //PA15配置为外部中断源(本质利用AFIO_EXTICR寄存器)
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5); //PC5配置为外部中断源(本质利用AFIO_EXTICR寄存器)
}

void NVIC_Configuration(void) // 嵌套向量中断初始化
{
	NVIC_InitTypeDef NVIC_InitStructure; 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 中断优先级分组
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; // EXTI9_5中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //占先优先级设定,取值为0-1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级设定、取值0-7
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn; //EXTI9_5中断源
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占先优先设计定,取值为0-1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级设计定,取值为0-7
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void EXTI9_5_IRQHandler(void) // 外部中断源9_5中断子程序
{
	if(EXTI_GetITStatus(EXTI_Line5) != RESET)
	{
		flag=1;
		EXTI_ClearFlag(EXTI_Line5);
	}

}

void EXTI15_10_IRQHandler(void) // 外部中断源15_10中断子程序
{
	if (EXTI_GetITStatus(EXTI_Line15)!=RESET)
	{
		flag=0;
		EXTI_ClearFlag(EXTI_Line15);
	}
}

void delay_nms(u16 time) //延时
{
	u16 i=0;
	while(time--)
	{
		i = 4000;
		while(i--);
	}
}


12、USART(串口通信)

/*
	基本的USART代码
	通过USART1发送数据、PC机上运行串口调试助手软件接收字符
	如果串口没有显示正确的输出,检查Target/Code Generation中的Use MicroLIB项是否被选中
*/
#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>

#define RxBufferSize 10

void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void NVIC_Configuration(void);
int fputc(int ch, FILE *f);/*重定向,修改一下选中Use MicroLIB ,
							需要在 Target/Code Generation??Use MicroLIB
							才能使用printf	*/
void delay_nms(u16 time);//延时子程序

unsigned char RxBuffer[RxBufferSize];
unsigned char CmdBuffer[RxBufferSize];
unsigned char Rx_Flag = 0;
unsigned char RxCounter=0;
u16 i;


int main(void)
{
	RCC_Configuration();
	GPIO_Configuration();
	USART_Configuration();
	NVIC_Configuration();
	
	USART_ClearFlag(USART1,USART_FLAG_TC);// 清发送结束位
	USART_SendData(USART1, 'A'); // 向发送数据寄存器写一个字节
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
	USART_SendData(USART1,'B');
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
	printf("\r\n");
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
	printf("zzzz\n");
	
	printf("打开LED灯,请输入 ON!\n"); 
	printf("关闭LED灯,请输入 OFF!\n"); 
	printf("输入错误的话,LED闪烁10次!\n");

	GPIO_SetBits(GPIOA,GPIO_Pin_8);//PA8置位,LED1灯灭
	memset(CmdBuffer,10,0);
	while(1)
	{
		if (Rx_Flag == 1)
		{
			USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); //关闭接收中断
			Rx_Flag = 0;
			RxCounter=0;
			if(strstr(CmdBuffer,"OFF"))
			{
				GPIO_SetBits(GPIOA,GPIO_Pin_8);//PA8置位,LED1灯灭
				memset(CmdBuffer,10,0);
			}
			else if(strstr(CmdBuffer,"ON"))
			{
				GPIO_ResetBits(GPIOA,GPIO_Pin_8);
				memset(CmdBuffer,10,0);
			}
			else
			{
				memset(CmdBuffer,10,0);
				for (i=0;i<10;i++)
				{
					GPIO_ResetBits(GPIOA,GPIO_Pin_8);//PA8清零,LED1灯亮
					delay_nms(200); 
					GPIO_SetBits(GPIOA,GPIO_Pin_8);//PA8置位,LED1灯灭 
					delay_nms(200);
				}
			}
			USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断,接收寄存器不空(RXNE = 1)时产生中断
		}
	}
}

void RCC_Configuration(void)
{ 
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1的时钟
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构变量
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //配置管脚PA10/USART1_RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// 浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA10
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //配置管脚PA9/USART1_TX
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //IO配置为复用输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //配置管脚8
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //IO口配置为推挽输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //工作频率50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA8口
}


void NVIC_Configuration(void) //NVIC配置
{ 
	//配置NVIC的优先级
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //优先级分组1(0:4, 0位抢占优先级、4位子优先级?
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //设置串口1 中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级位0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 串口中断使能
	NVIC_Init(&NVIC_InitStructure);
}

void USART_Configuration(void)
{
	USART_InitTypeDef USART_InitStructure;
	
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; //USART_WordLength_8b; //8 数据 //USART_WordLength_9b; //9 位数据
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	//USART_StopBits_1 ;//在帧结尾传输1个停止位
	//USART_StopBits_0.5;//在帧结尾传输0.5个停止位
	//USART_StopBits_2 ;//在帧结尾传输2个停止位
	//USART_StopBits_1.5;//在帧结尾传输1.5个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	//USART_Parity_No ;//奇偶失能
	//USART_Parity_Even;//偶模式
	//USART_Parity_Odd ;//奇模式
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//USART_HardwareFlowControl_None; //硬件流控制失能
	//USART_HardwareFlowControl_RTS; //发送请求 RTS使能
	//USART_HardwareFlowControl_CTS; //清除请求 CTS使能
	//USART_HardwareFlowControl_RTS_CTS;//RTS和 CTS使能
	USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
	//USART_Mode_Tx;//发送使能
	//USART_Mode_Rx;//接收使能
	USART_Init(USART1, &USART_InitStructure);//初始化串口
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断,接收寄存器不空(RXNE=1)时产生中断
	//USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断,发送寄存器空(TXE=1)时使能产生中断
	/*串口的发送中断有两个,分别是:
			l、发送数据寄存器空中断(TXE)
			2、发送完成中断(TC)*/
	USART_Cmd(USART1, ENABLE); //启动USART
}

int fputc(int ch,FILE *f)
{
	if(ch=='\n')
	{
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
		USART_SendData(USART1,'\r');
	}
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET)
	;
	USART_SendData(USART1,ch);
	return ch;
}

void delay_nms(u16 time)//延时子程序
{ 
	u16 i=0;
	while(time--)
	{ 
		i=12000; 
		while(i--) ;
	}
}

void USART1_IRQHandler(void) //串口1 中断服务程序
{
	unsigned int i=0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断接收寄存器是否为空
	{
		//如果接收寄存器非空,说明检测到中断读入
		RxBuffer[RxCounter++] = USART_ReceiveData(USART1); // Read one byte from the receive data register
		if (RxBuffer[RxCounter-1]=='\n') //如果检测到换行,则设置接收标志位为1
		// \n:换行,光标到下行行首
		// \r:回车,光标到本行行首
		{
			Rx_Flag=1;
			for (i=0;i<RxCounter;i++)//把接收的数据缓存到CmdBuffer中
			{
				CmdBuffer[i]=RxBuffer[i];
			}
			CmdBuffer[RxCounter]=0; //发送缓冲区结束符
			RxCounter=0;
		}
		if(RxCounter == RxBufferSize) //如菇邮整缓冲区满了
		{
			USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); //关闭接收中断
			Rx_Flag=1;
			CmdBuffer[RxCounter]=0; //接收命令缓冲区结束符
			RxCounter=0;
		}
	}
}


USART转发

/*
	PA9->USARTI_TX
	PA10->USART1_RX
	利用USART的中断进行接收和发送数据
	用到了串口助手
	ps:注意晶振的频率
	*/
#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>

#define TxBufferSize (countof(TxBuffer) - 1) //定义UART1的发送缓冲器的字节数
#define RxBufferSize 0x51 //定义USART1的接收缓冲器的字节数
#define countof(a) (sizeof(a) / sizeof(*(a)))

u8 TxBuffer[] = "Stm32.USART->Computer. Developed by Ph.D. A. Dong, Qilu Univerity of Technology.\r\n" ;
u8 RxBuffer[RxBufferSize];
u8 NbrOfDataToTransfer = TxBufferSize;
u8 NbrOfDataToRead = RxBufferSize;
u8 TxCounter = 0;
u16 RxCounter = 0;
u8 Tx_Flag=0;
u8 Rx_Flag=0;

void RCC_Configuration(void); //时钟配置
void GPIO_Configuration(void); //GOPO配置
void USART_Configuration(void);//USART配置
void NVIC_Configuration(void);//NVIC配置
void delay_nms(u16 time);//延时子程序
unsigned int i;


int main(void)
{	
	RCC_Configuration(); //配置时钟
	NVIC_Configuration();//配置NVIC
	GPIO_Configuration(); //配置GPIO
	USART_Configuration();//配置USART

	while(1)
	{
		USART_ClearFlag(USART1,USART_FLAG_TC);//清发送结束位
		USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送
		delay_nms(2000);
		
		if(Rx_Flag==1) //如果接收到的一组以换行结束的数据,则将接收到的数据在发送出去
		{ 
			//判断是否接收到一帧有效数据
			Rx_Flag=0;
			for(i=0; i< NbrOfDataToRead; i++) TxBuffer[i] = 0;
			// TxBuffer[0]='\n';
			// TxBuffer[1]='\r';
			for(i=0; i< RxCounter; i++) TxBuffer[i] = RxBuffer[i];
			//TxBuffer[RxCounter]='\r';
			//TxBuffer[RxCounter+1]='\n';
			//TxBuffer[RxCounter+2]='\r';
			//将接收缓冲器的数据转到发送缓冲区,并在缓冲区头上加上换行符,准备转发
			RxCounter=0;
			USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断,接收寄存器不空(RXNE=1)时产生中断
			USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //开启发送中断
			delay_nms(2000);
		}
	}
}

void RCC_Configuration(void) // 时钟配置子程序
{ 
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1的时钟, USART1挂接到APB2上。其他USART2-5挂接到APB!上
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // 使能AFIO的时钟,串口属于复用功能
}

void GPIO_Configuration(void) // GPIO配置
{
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构变量
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //配置管脚PA10/USART1_RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// 浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA10
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //配置管脚PA9/USART1_TX
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //IO配置为复用输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9

}


void NVIC_Configuration(void) //NVIC配置
{ 
	//配置NVIC相应的优先级位
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //优先级分组1(1:3,1位抢占优先级、3位子优先级)
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //设置串口1中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级为0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 串口中断使能
	NVIC_Init(&NVIC_InitStructure);
}

void USART_Configuration(void)
{
	USART_InitTypeDef USART_InitStructure;
	
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; //USART_WordLength_8b; //8 数据 //USART_WordLength_9b; //9 位数据
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	//USART_StopBits_1 ;//在帧结尾传输1个停止位
	//USART_StopBits_0.5;//在帧结尾传输0.5个停止位
	//USART_StopBits_2 ;//在帧结尾传输2个停止位
	//USART_StopBits_1.5;//在帧结尾传输1.5个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	//USART_Parity_No ;//奇偶失能
	//USART_Parity_Even;//偶模式
	//USART_Parity_Odd ;//奇模式
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//USART_HardwareFlowControl_None; //硬件流控制失能
	//USART_HardwareFlowControl_RTS; //发送请求 RTS使能
	//USART_HardwareFlowControl_CTS; //清除请求 CTS使能
	//USART_HardwareFlowControl_RTS_CTS;//RTS和 CTS使能
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	//USART_Mode_Tx;//发送使能
	//USART_Mode_Rx;//接收使能
	USART_Init(USART1, &USART_InitStructure);//初始化串口
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断,接收寄存器不空(RXNE=1)时产生中断
	USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断,发送寄存器空(TXE=1)时使能产生中断
	/*串口的发送中断有两个,分别是:
			l、发送数据寄存器空中断(TXE)
			2、发送完成中断(TC)*/
	USART_Cmd(USART1, ENABLE); //启动USART
}

void delay_nms(u16 time)//延时子程序
{ 
	u16 i=0;
	while(time--)
	{ 
		i=12000; 
		while(i--) ;
	}
}

void USART1_IRQHandler(void) //串口1 中断服务程序
{
	unsigned int i=0;
	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断接收寄存器是否非空
	{
		//当检测到中断读入
		RxBuffer[RxCounter++] = USART_ReceiveData(USART1); // Read one byte from the receive data register
		if (RxBuffer[RxCounter-1]=='\n') //如果检测到换行,则设置接收标志位1
		// \n:换行,光标到下行行首
		// \r:回车,光标到本行行首
		{
			Rx_Flag=1;
			TxBuffer[RxCounter]=0; //发送缓冲区结束符
		}
		
		if(RxCounter == NbrOfDataToRead) //如果接收缓冲区满了
		{
			USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); //关闭接收中断
			Rx_Flag=1;
			TxBuffer[RxCounter]=0; //发送缓冲区结束符
		}
	}
	
	if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
	{ 
		//当检测到发送中断
		USART_SendData(USART1, TxBuffer[TxCounter++]); //向发送数据寄存器写一个字节
		if(TxCounter == NbrOfDataToTransfer)
		{
			TxCounter=0;
			USART_ITConfig(USART1, USART_IT_TXE, DISABLE); /* Disable the USART1 Transmit interrupt */
		}
	}
	
}


13、DMA实例

(1)存储器至存储器传输

#include "stm32f10x.h"
#include <stdio.h>

void RCC_Configuration(void);
void GPIO_Configuration(void);
void DMA_Configuration(void);
void USART_Configuration(void);
int fputc(int ch, FILE *f);//重定向
void delay_nms(u16 time);

uint8_t SrcBuf[10]="Hello DMA";
uint8_t DstBuf[10]="DMA Hello";

int main(void)
{
	RCC_Configuration();
	GPIO_Configuration();
	USART_Configuration();
	DMA_Configuration();
	USART_ClearFlag(USART1,USART_FLAG_TC);//清发送结束位
	// USART_SendData(USART1, 'A'); //向发送数据寄存器写一个字节
	// while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
	// USART_SendData(USART1,'B');
	
	printf("Before the DMA transfer:\n");
	printf("DstBuf: %s\n",DstBuf);
	DMA_Cmd(DMA1_Channel1,ENABLE);
	printf("After the DMA transfer:\n");
	printf("DstBuf: %s\n",DstBuf);
	
	while(1)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_8); 
		delay_nms(200);
		GPIO_ResetBits(GPIOA,GPIO_Pin_8); 
		delay_nms(200);
	}
}

void RCC_Configuration(void)
{ 
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1的时钟, USART1挂接到APB2上
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
}
	
void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构变量
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //配置管脚PA10/USART1_RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// 浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA10
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //配置管脚PA9/USART1_TX
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //IO配置为复用输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //配置管脚8
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //IO口配置为复用输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //工作频率50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA8口
}


void DMA_Configuration(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	/* DMA channel1 configuration */
	DMA_DeInit(DMA1_Channel1);//重置DMA的寄存器的值,配置为缺省值
	DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)SrcBuf;/*设置DMA外设基地址,即源数据存储区的首地址*/
	DMA_InitStructure.DMA_MemoryBaseAddr =(u32)DstBuf;/*定义内存基地址*/
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;/*设置数据传输方向,从外设读取数据*/
	// DMA_DIR_PeripheralSRC // 两种传输方向的设置
	// DMA_DIR_PeripheralDST
	
	DMA_InitStructure.DMA_BufferSize = 10;/*指定DMA通道,DMA缓存的大小*/
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;/*设置外设数据指针调整模数,地址指针自动增加*/
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*设置内存地址递增*/
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;/* 定义外设和内存的数据宽度 */
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;/* 设定DMA工作正常模式,即按照指定的缓存大传输,不在进行循环 */
	DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; // 开启存储器到存储器模式
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
}
	
void USART_Configuration(void)
{
	USART_InitTypeDef USART_InitStructure;
	
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; //USART_WordLength_8b; //8 数据 //USART_WordLength_9b; //9 位数据
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	//USART_StopBits_1 ;//在帧结尾传输1个停止位
	//USART_StopBits_0.5;//在帧结尾传输0.5个停止位
	//USART_StopBits_2 ;//在帧结尾传输2个停止位
	//USART_StopBits_1.5;//在帧结尾传输1.5个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	//USART_Parity_No ;//奇偶失能
	//USART_Parity_Even;//偶模式
	//USART_Parity_Odd ;//奇模式
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//USART_HardwareFlowControl_None; //硬件流控制失能
	//USART_HardwareFlowControl_RTS; //发送请求 RTS使能
	//USART_HardwareFlowControl_CTS; //清除请求 CTS使能
	//USART_HardwareFlowControl_RTS_CTS;//RTS和 CTS使能
	USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
	//USART_Mode_Tx;//发送使能
	//USART_Mode_Rx;//接收使能
	USART_Init(USART1, &USART_InitStructure);//初始化串口
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断,接收寄存器不空(RXNE=1)时产生中断
	//USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断,发送寄存器空(TXE=1)时使能产生中断
	/*串口的发送中断有两个,分别是:
			l、发送数据寄存器空中断(TXE)
			2、发送完成中断(TC)*/
	USART_Cmd(USART1, ENABLE); //启动USART
}
	
int fputc(int ch,FILE *f)
{
	if(ch=='\n')
	{
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
		USART_SendData(USART1,'\r');
	}
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET)
	;
	USART_SendData(USART1,ch);
	return ch;
}

void delay_nms(u16 time)//延时子程序
{ 
	u16 i=0;
	while(time--)
	{ 
		i=12000; 
		while(i--) ;
	}
}
	
	

(2)DMA存储器到外设传输

使用前再main方法里面调用代码

	USART_ClearFlag(USART1,USART_FLAG_TC);//清发送结束位
	USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
	DMA_Cmd(DMA1_Channel4, ENABLE);

DMA的配置:

void DMA_Configuration(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	/* DMA channel1 configuration */
	DMA_DeInit(DMA1_Channel4);//重置DMA的寄存器的值,配置为缺省值
	DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&USART1->DR;/*设置DMA外设基地址,即源数据存储区的首地址*/
	DMA_InitStructure.DMA_MemoryBaseAddr =(u32)SrcBuf;/*定义内存基地址*/
//	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;/*设置数据传输方向,从外设读取数据*/
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
	// DMA_DIR_PeripheralSRC // 两种传输方向的设置
	// DMA_DIR_PeripheralDST
	
	DMA_InitStructure.DMA_BufferSize = 11;/*指定DMA通道,DMA缓存的大小*/
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;/*设置外设数据指针调整模数,地址指针自动增加*/
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*设置内存地址递增*/
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;/* 定义外设和内存的数据宽度 */
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;/* 设定DMA工作正常模式,即按照指定的缓存大传输,不在进行循环 */
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;/*设定DMA选定的通道的软件优先级*/
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 开启存储器到存储器模式
	DMA_Init(DMA1_Channel4, &DMA_InitStructure);
}

其他的同(1)代码

(3)DMA外设到存储器传输

#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>


void RCC_Configuration(void);
void GPIO_Configuration(void);
void DMA_Configuration(void);
void USART_Configuration(void);
int fputc(int ch, FILE *f);


void delay_nms(u16 time);//?????

char SrcBuf[12]="xxxxxxxxxxx"; 

int main(void)
{
	char flag = 1;
	
	RCC_Configuration();
	GPIO_Configuration();
	USART_Configuration();
	DMA_Configuration();
	
	USART_ClearFlag(USART1,USART_FLAG_TC);//清发送位
	USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);//允许USART接收DMA请求
	DMA_Cmd(DMA1_Channel5, ENABLE); // 启动DMA
	
	while(flag)
	{
			if(strstr(SrcBuf, "LED"))
			{
				printf(SrcBuf);
				flag = 0;
			}
	}
	
	while(1)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_8); 
		delay_nms(200);
		GPIO_ResetBits(GPIOA,GPIO_Pin_8); 
		delay_nms(200);
	}
}

void RCC_Configuration(void)
{ 
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1的时钟, USART1挂接到APB2上
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
}
	
void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构变量
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //配置管脚PA10/USART1_RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// 浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA10
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //配置管脚PA9/USART1_TX
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //IO配置为复用输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //配置管脚8
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //IO口配置为复用输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //工作频率50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA8口
}

void DMA_Configuration(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	/* DMA channel1 configuration */
	DMA_DeInit(DMA1_Channel5);//重置DMA的寄存器的值,配置为缺省值
	DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&USART1->DR;/*设置DMA外设基地址,即源数据存储区的首地址*/
	DMA_InitStructure.DMA_MemoryBaseAddr =(u32)SrcBuf;/*定义内存基地址*/
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;/*设置数据传输方向为从内存到外设*/
//	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
	
	DMA_InitStructure.DMA_BufferSize = 11;/*指定DMA通道,DMA缓存的大小*/
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;/*外设地址不变*/
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*内存地址递增*/
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;/*定义外设和内存的数据宽度*/
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;/*设定DMA工作正常模式,即按照指定的缓存大小传输,不在进行循环*/
	// DMA_Mode_Circular 循环模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;/*设定DMA选定的通道的软件的优先级*/
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//关闭存储器到存储器模式
	DMA_Init(DMA1_Channel5, &DMA_InitStructure); // 初始化DMA1_Channel5
}
	
void USART_Configuration(void)
{
	USART_InitTypeDef USART_InitStructure;
	
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; //USART_WordLength_8b; //8 数据 //USART_WordLength_9b; //9 位数据
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	//USART_StopBits_1 ;//在帧结尾传输1个停止位
	//USART_StopBits_0.5;//在帧结尾传输0.5个停止位
	//USART_StopBits_2 ;//在帧结尾传输2个停止位
	//USART_StopBits_1.5;//在帧结尾传输1.5个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	//USART_Parity_No ;//奇偶失能
	//USART_Parity_Even;//偶模式
	//USART_Parity_Odd ;//奇模式
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//USART_HardwareFlowControl_None; //硬件流控制失能
	//USART_HardwareFlowControl_RTS; //发送请求 RTS使能
	//USART_HardwareFlowControl_CTS; //清除请求 CTS使能
	//USART_HardwareFlowControl_RTS_CTS;//RTS和 CTS使能
	USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
	//USART_Mode_Tx;//发送使能
	//USART_Mode_Rx;//接收使能
	USART_Init(USART1, &USART_InitStructure);//初始化串口
	//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断,接收寄存器不空(RXNE=1)时产生中断
	//USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断,发送寄存器空(TXE=1)时使能产生中断
	/*串口的发送中断有两个,分别是:
			l、发送数据寄存器空中断(TXE)
			2、发送完成中断(TC)*/
	USART_Cmd(USART1, ENABLE); //启动USART
}
	
int fputc(int ch,FILE *f)
{
	if(ch=='\n')
	{
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
		USART_SendData(USART1,'\r');
	}
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET)
	;
	USART_SendData(USART1,ch);
	return ch;
}

void delay_nms(u16 time)//延时子程序
{ 
	u16 i=0;
	while(time--)
	{ 
		i=12000; 
		while(i--) ;
	}
}
	
	

14、ADC,DAC

利用ADC,获得内部电压,和温度

#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>

#define ADC_CH_TEMP  	ADC_Channel_16 //温度传感器通道

void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void NVIC_Configuration(void);

//电压的
u16 Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);
void Adc_Init(void);

//温度的
void T_Adc_Init(void);
u16 T_Get_Adc(u8 ch);
u16 T_Get_Temp(void);
u16 T_Get_Adc_Average(u8 ch,u8 times);

u16 adcx;
float temp;
float temperate;

int fputc(int ch, FILE *f);//输出重定向
void delay_nms(u16 time);

int main(void)
{
	RCC_Configuration();
	GPIO_Configuration();
	USART_Configuration();
	NVIC_Configuration();
	
	Adc_Init(); // 电压的
	T_Adc_Init();// 温度的
	
	while(1)
	{
		adcx = Get_Adc_Average(ADC_Channel_1,10);
		temp = (float)adcx*(3.3/4096);
		printf("ADC的值为:%d, 转化为电压是:%lfV,   QLU_fuchen \n", adcx, temp);
    
		
		adcx = T_Get_Adc_Average(ADC_CH_TEMP, 10);
		temp = (float)adcx * (3.3 / 4096);
		temperate = temp;
		temperate = (1.43 - temperate) / 0.0043 + 25;
		printf("ADC的值为:%d, 转化为温度是:%lf℃,   QLU_fuchen \n", adcx, temperate);
		
		printf("\n");
		
		delay_nms(2000);
	}
}

void RCC_Configuration(void)
{ 
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1的时钟
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构变量
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //配置管脚PA10/USART1_RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// 浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA10
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //配置管脚PA9/USART1_TX
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //IO配置为复用输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //配置管脚8
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //IO口配置为推挽输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //工作频率50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA8口
}

void NVIC_Configuration(void) //NVIC配置
{ 
	//配置NVIC的优先级
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //优先级分组1(0:4, 0位抢占优先级、4位子优先级?
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //设置串口1 中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级位0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 串口中断使能
	NVIC_Init(&NVIC_InitStructure);
}

void USART_Configuration(void)
{
	USART_InitTypeDef USART_InitStructure;
	
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; //USART_WordLength_8b; //8 数据 //USART_WordLength_9b; //9 位数据
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	//USART_StopBits_1 ;//在帧结尾传输1个停止位
	//USART_StopBits_0.5;//在帧结尾传输0.5个停止位
	//USART_StopBits_2 ;//在帧结尾传输2个停止位
	//USART_StopBits_1.5;//在帧结尾传输1.5个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	//USART_Parity_No ;//奇偶失能
	//USART_Parity_Even;//偶模式
	//USART_Parity_Odd ;//奇模式
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//USART_HardwareFlowControl_None; //硬件流控制失能
	//USART_HardwareFlowControl_RTS; //发送请求 RTS使能
	//USART_HardwareFlowControl_CTS; //清除请求 CTS使能
	//USART_HardwareFlowControl_RTS_CTS;//RTS和 CTS使能
	USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
	//USART_Mode_Tx;//发送使能
	//USART_Mode_Rx;//接收使能
	USART_Init(USART1, &USART_InitStructure);//初始化串口
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断,接收寄存器不空(RXNE=1)时产生中断
	//USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断,发送寄存器空(TXE=1)时使能产生中断
	/*串口的发送中断有两个,分别是:
			l、发送数据寄存器空中断(TXE)
			2、发送完成中断(TC)*/
	USART_Cmd(USART1, ENABLE); //启动USART
}

int fputc(int ch,FILE *f)
{
	if(ch=='\n')
	{
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
		USART_SendData(USART1,'\r');
	}
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET)
	;
	USART_SendData(USART1,ch);
	return ch;
}

void delay_nms(u16 time)//?????
{ 
	u16 i=0;
	while(time--)
	{ 
		i=12000; 
		while(i--) ;
	}
}


//下面是电压的代码
void  Adc_Init(void)
{ 	
	ADC_InitTypeDef ADC_InitStructure; 
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1	, ENABLE );	  //使能ADC1通道时钟
 

	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

	//PA1 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

	ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在单通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//模数转换工作在单次转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

  
	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	 
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
 
//	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能

}				  


u16 Get_Adc(u8 ch)   
{
  	//设置指定ADC的规则组通道,一个序列,采样时间
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );	//ADC1,ADC通道,采样时间为239.5周期	  			    
  
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能	
	 
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束

	return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
}


u16 Get_Adc_Average(u8 ch,u8 times)
{
	u32 temp_val=0;
	u8 t;
	for(t=0;t<times;t++)
	{
		temp_val+=Get_Adc(ch);
		delay_nms(5);
	}
	return temp_val/times;
} 


// 下面的温度的代码

//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3	
void T_Adc_Init(void)  //ADC通道初始化
{
	ADC_InitTypeDef ADC_InitStructure; 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );	  //使能GPIOA,ADC1通道时钟
  
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //分频因子6时钟为72M/6=12MHz

	ADC_DeInit(ADC1);  //将外设 ADC1 的全部寄存器重设为缺省值
 
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在单通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//模数转换工作在单次转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器

	ADC_TempSensorVrefintCmd(ENABLE); //开启内部温度传感器
	
 
	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1

	ADC_ResetCalibration(ADC1);	//重置指定的ADC1的复位寄存器

    while(ADC_GetResetCalibrationStatus(ADC1));	//获取ADC1重置校准寄存器的状态,设置状态则等待

	ADC_StartCalibration(ADC1);	 //

	while(ADC_GetCalibrationStatus(ADC1));		//获取指定ADC1的校准程序,设置状态则等待
}

u16 T_Get_Adc(u8 ch)   
	{
 
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );	//ADC1,ADC通道3,第一个转换,采样时间为239.5周期	  			    
 
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
	return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
	}

//得到ADC采样内部温度传感器的值
//取10次,然后平均
u16 T_Get_Temp(void)
	{
	u16 temp_val=0;
	u8 t;
	for(t=0;t<10;t++)
		{
		temp_val+=T_Get_Adc(ADC_Channel_16);	  //TampSensor
		delay_nms(5);
		}
	return temp_val/10;
	}

 //获取通道ch的转换值
//取times次,然后平均
u16 T_Get_Adc_Average(u8 ch,u8 times)
{
	u32 temp_val=0;
	u8 t;
	for(t=0;t<times;t++)
	{
		temp_val+=T_Get_Adc(ch);
		delay_nms(5);
	}
	return temp_val/times;
} 	

获取DAC通道中存储的数值,并转化为相应的电压通过串口显示

#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>

void Dac1_Init(void);	//DAC通道1初始化	

void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void EXTI_Configuration(void);
void NVIC_Configuration(void);
int fputc(int ch, FILE *f);// 输出重定向

void delay_ms(u16 time);

void Adc_Init(void); // ADC的初始化
void Dac1_Init(void); //DAC通道1的初始化
u16 Get_Adc(u8 ch); // 获取 ADC通道值
u16 Get_Adc_Average(u8 ch,u8 times); // 获取一段时间内通道的平均值

u16 adcx;
float temp;
char flag = 0;
u16 dacval = 1000;

int main(void)
{
	RCC_Configuration();
	GPIO_Configuration();
	USART_Configuration();
	EXTI_Configuration(); // 配置外部中断源
	NVIC_Configuration(); // 嵌套向量中断初始化
	
	Adc_Init();		  		//ADC初始化
	Dac1_Init();		 	//DAC通道1初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	u8 t = 0;
	
	DAC_SetChannel1Data(DAC_Align_12b_R, dacval);

	while(1)
	{
			while(1)
		{
			t++;	  
			if(t == 2) //两次刷新一次
			{	  
				adcx=DAC_GetDataOutputValue(DAC_Channel_1); //获取DAC通道存储的数值
				printf("DAC VAL: %d.\n", adcx);
				
				temp=(float)adcx*(3.3/4096);			//得到DAC电压值
				printf("DAC VOL: %lfV\n", temp);

				adcx=Get_Adc_Average(ADC_Channel_1,10);		//得到ADC转换值	  
				temp=(float)adcx*(3.3/4096);			//得到ADC电压值
				printf("ADC VOL:%lfV\n", temp);
  
				t=0;
				printf("\n\n");
			}	    
			delay_ms(1000);	
		}
	}
}

void RCC_Configuration(void)
{ 
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能AFIO时钟(开始管脚的复用功能)
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //关掉JTAG,不关SW
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构变量 
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //配置管脚PA10/USART1_RX
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// 浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9; //配置管脚PA9/USART1_TX
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //IO配置为复用输出口  
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //IO口配置为推挽输出口
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;  
	GPIO_Init(GPIOA,&GPIO_InitStructure);  
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5; 
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU ; 
	GPIO_Init(GPIOC,&GPIO_InitStructure); 
}


void EXTI_Configuration(void) // 配置外部中断源
{
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line=EXTI_Line15|EXTI_Line5; // 外部中短线Line12 | Line5
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //选择中断模式
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发
	EXTI_InitStructure.EXTI_LineCmd=ENABLE; //使能中断
	EXTI_Init(&EXTI_InitStructure);  // 初始化外部中断
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15); //PA15配置为外部中断源(本质利用AFIO_EXTICR寄存器)
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5); //PC5配置为外部中断源(本质利用AFIO_EXTICR寄存器)
}

void NVIC_Configuration(void) // 嵌套向量中断初始化
{
	NVIC_InitTypeDef NVIC_InitStructure; 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 中断优先级分组
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; // EXTI9_5中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //占先优先级设定,取值为0-1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级设定、取值0-7
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn; //EXTI9_5中断源
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //占先优先设计定,取值为0-1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级设计定,取值为0-7
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void EXTI9_5_IRQHandler(void) // 外部中断源9_5中断子程序
{
	if(EXTI_GetITStatus(EXTI_Line5) != RESET)
	{
		if(dacval < 4000){
			dacval += 200;
		}
		DAC_SetChannel1Data(DAC_Align_12b_R, dacval);
		EXTI_ClearFlag(EXTI_Line5);
	}

}

void EXTI15_10_IRQHandler(void) // 外部中断源15_10中断子程序
{
	if (EXTI_GetITStatus(EXTI_Line15)!=RESET)
	{
		if(dacval>200)dacval -= 200;
			else dacval=0;
		
		DAC_SetChannel1Data(DAC_Align_12b_R, dacval);
		EXTI_ClearFlag(EXTI_Line15);
	}
}

void USART_Configuration(void)
{
	USART_InitTypeDef USART_InitStructure;
	
	USART_InitStructure.USART_BaudRate = 115200;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; //USART_WordLength_8b; //8 数据 //USART_WordLength_9b; //9 位数据
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	//USART_StopBits_1 ;//在帧结尾传输1个停止位
	//USART_StopBits_0.5;//在帧结尾传输0.5个停止位
	//USART_StopBits_2 ;//在帧结尾传输2个停止位
	//USART_StopBits_1.5;//在帧结尾传输1.5个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;
	//USART_Parity_No ;//奇偶失能
	//USART_Parity_Even;//偶模式
	//USART_Parity_Odd ;//奇模式
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	//USART_HardwareFlowControl_None; //硬件流控制失能
	//USART_HardwareFlowControl_RTS; //发送请求 RTS使能
	//USART_HardwareFlowControl_CTS; //清除请求 CTS使能
	//USART_HardwareFlowControl_RTS_CTS;//RTS和 CTS使能
	USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
	//USART_Mode_Tx;//发送使能
	//USART_Mode_Rx;//接收使能
	USART_Init(USART1, &USART_InitStructure);//初始化串口
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断,接收寄存器不空(RXNE=1)时产生中断
	//USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断,发送寄存器空(TXE=1)时使能产生中断
	/*串口的发送中断有两个,分别是:
			l、发送数据寄存器空中断(TXE)
			2、发送完成中断(TC)*/
	USART_Cmd(USART1, ENABLE); //启动USART
}

int fputc(int ch,FILE *f)
{
	if(ch=='\n')
	{
		while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
		USART_SendData(USART1,'\r');
	}
	while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET)
	;
	USART_SendData(USART1,ch);
	return ch;
}

void delay_ms(u16 time)
{ 
	u16 i=0;
	while(time--)
	{ 
		i=12000; 
		while(i--) ;
	}
}

//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3																	   
void Adc_Init(void)
{ 	
	ADC_InitTypeDef ADC_InitStructure; 
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1	, ENABLE );	  //使能ADC1通道时钟
 

	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

	//PA1 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

	ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在单通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//模数转换工作在单次转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

  
	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	 
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
 
//	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能

}				  

//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{
  	//设置指定ADC的规则组通道,一个序列,采样时间
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );	//ADC1,ADC通道,采样时间为239.5周期	  			    
  
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能	
	 
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束

	return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
}

u16 Get_Adc_Average(u8 ch,u8 times)
{
	u32 temp_val=0;
	u8 t;
	for(t=0;t<times;t++)
	{
		temp_val+=Get_Adc(ch);
		delay_ms(5);
	}
	return temp_val/times;
} 	 

//DAC通道1输出初始化
void Dac1_Init(void)
{
  
	GPIO_InitTypeDef GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitType;

	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; 		 //模拟输入
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_4)	;//PA.4 输出高
					
	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值

}


15、SysTic

精确延时

#include "stm32f10x.h"

#define LED GPIO_Pin_2 //定义LED对应的管脚

void RCC_Configuration(void); //时钟配置
void TIM_Configuration(void);
void NVIC_Configuration(void); //NVIC配置
void GPIO_Configuration(void); //GPIO配置


int main(void)
{ 
	RCC_Configuration();//配置时钟
	GPIO_Configuration(); //配置GPIO, 注意,一定要先配置GPIO,在配置TIM和NVIC,否则无效
	TIM_Configuration();
	NVIC_Configuration();//配置NVIC
	GPIO_ResetBits(GPIOA, LED);//PBA清零,LED亮
	while(1){}
}

void RCC_Configuration(void)//时钟配置子程序
{ 
	SystemInit(); //72MHz
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//使能GPIOD的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能TIM2的时钟
}

void GPIO_Configuration(void) //GPIO配置
{ /*管脚设置*/
	GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构体变量
	GPIO_InitStructure.GPIO_Pin = LED; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void NVIC_Configuration(void) //NVIC配置
{ //配置NVIC相应的优先级位
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; ;// 设置TIM2中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级为 0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 串口中断使能
	NVIC_Init(&NVIC_InitStructure);
}

void TIM_Configuration(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能TIM2的时钟
	TIM_TimeBaseInitTypeDef TIM_BaseInitStructure;
	TIM_BaseInitStructure.TIM_Prescaler = 36000-1; //预分频数值,72 000 000/36000=2000Hz
	TIM_BaseInitStructure.TIM_Period = 1000-1; //预装载值,从0记数至1000后,产生中断信号,累计0.5s
	TIM_BaseInitStructure.TIM_ClockDivision = 0;
	TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//上升计数模式
	TIM_BaseInitStructure.TIM_RepetitionCounter = TIM_CKD_DIV1;//滤波器采样分频
	TIM_TimeBaseInit(TIM2, &TIM_BaseInitStructure); //清中断,以免一启用中断后立即产生中断
	TIM_UpdateRequestConfig(TIM2, TIM_UpdateSource_Regular);
	//TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	//使能TIM2中断源
	TIM_Cmd(TIM2, ENABLE);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//TIM2总开关:开启
}


void TIM2_IRQHandler(void){
	if(TIM_GetITStatus(TIM2, TIM_IT_Update)== SET)
	{
		GPIOD->ODR ^= LED; //异或使LED状态改变
		TIM_ClearITPendingBit(TIM2, TIM_FLAG_Update); //清除中断标志
	}
}


呼吸灯

#include "stm32f10x.h"

void RCC_Configuration(void); 
void TIM_Configuration(void);
void GPIO_Configuration(void);
void PWM_Configuration(void);
void delay_ms(u16 time);

int led_fx = 1;
int led_dt = 0;

int main(void)
{
	RCC_Configuration();
	GPIO_Configuration(); // GPIO要先于 TIM和NVIC配置
	TIM_Configuration();
	PWM_Configuration();
	
	TIM_Cmd(TIM1, ENABLE); // 使能TIM计时器,开始输出PWM
	
	while(1)
	{
		delay_ms(5);
		if(led_fx == 1)
		{
			led_dt++;
		}
		else
		{
			led_dt--;
		}
		
		if(led_dt > 300)
		{
			led_fx = 0;
		}
		else if(led_dt == 0)
		{
			led_fx = 1;
		}
		
		TIM_SetCompare1(TIM1, led_dt);
	}
	
}

void RCC_Configuration(void)//配置时钟
{ 
	SystemInit(); 
	//开启GPIO的时钟和复用功能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
	//开启TIM1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
}

void GPIO_Configuration(void) //GPIO配置
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM1, ENABLE); // 映射引脚,
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	//??????50MHz
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void TIM_Configuration(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_DeInit(TIM1); //重新将Timer设置为缺省值
	TIM_InternalClockConfig(TIM1); //采用内部时钟给TIM2提供时钟源
	TIM_TimeBaseStructure.TIM_Prescaler = 1-1; //预分频数值,72000 000/1=72000000
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)
															//使用的采样频率之间的分频比为1
	TIM_TimeBaseStructure.TIM_Period = 300-1; //设置计数溢出大小
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置计数器模式为向上计数模式(+1)
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //将配置应用到TIM2中
}

void PWM_Configuration(void)
{
	TIM_OCInitTypeDef TimOCInitStructure;
	//设置缺省值
	TIM_OCStructInit(&TimOCInitStructure);
	//PWM模式1输出
	TimOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	//设置占空比 (Led亮度)
	TimOCInitStructure.TIM_Pulse = 0;
	// TIM输出比较极性高
	TimOCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	//使能输出状态
	TimOCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	//TIM1的CH4输出
	TIM_OC1Init(TIM1, &TimOCInitStructure);
	//设置TIM1的PWM输出为使能
	TIM_CtrlPWMOutputs(TIM1, ENABLE);
}

void delay_ms(u16 time)
{
	u16 i = 0;
	while(time--)
	{
		i=12000;
		while(i--);
	}
}

TIM3产生4路PWM波

/**
2 ******************************************************************************
3 * @file TIM/PWM_Output/main.c
4 * @author MCD Application Team
5 * @version V3.5.0
6 * @date 08-April-2011
7 * @brief Main program body
8 ******************************************************************************
9 * @attention
10 // PA6===TIM3_Ch1, PA7===TIM3_Ch2
11 // PB0===TIM3_Ch3, PB1===TIM3_Ch4
12 */
 #include "stm32f10x.h"

 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
 TIM_OCInitTypeDef TIM_OCInitStructure;
 uint16_t CCR1_Val = 333;
 uint16_t CCR2_Val = 249;
 uint16_t CCR3_Val = 166;
 uint16_t CCR4_Val = 83;
 uint16_t PrescalerValue = 0;
/* Private function prototypes -----------------------------------------------*/
 void RCC_Configuration(void);
 void GPIO_Configuration(void);

int main(void)
 {
		RCC_Configuration();// System Clocks Configuration
		GPIO_Configuration();
	 
	 /* TIM3:产生4路PWM信号,每路具有不同的占空比
	 TIM3CLK频率设置为SystemCoreClock (Hz);

TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
35 TIM3的计数器时钟频率设置为24MHz,对应的预分频系数计算公式为:
36 - Prescaler = (TIM3CLK / TIM3 counter clock) - 1
37 SystemCoreClock=72 MHz
38
39 TIM3的工作频率为 36 KHz: TIM3 Frequency = TIM3 counter clock/(ARR + 1)
40 = 24 MHz / 666 = 36 KHz
41 TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
42 TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
43 TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
44 TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
45 ----------------------------------------------------------------------- */

		/* Compute the prescaler value */
		PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; //计算产生24MHz频率的分频系数
		/* Time base configuration */
		TIM_TimeBaseStructure.TIM_Period = 666-1; //设置自重重装载寄存器(ARR)的计数值
		TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;//预分频系数
		TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用
		//的采样频率之间的分频比例的(与输入捕获相关),0表示滤波器的频率和定时器的频率是一样的
		TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//上计数模式
		TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
		
		/* PWM1 Mode configuration: Channel1 */
		TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较模式=PWM输出模式1 (PWM输出有两种模式)
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能输出
		TIM_OCInitStructure.TIM_Pulse = CCR1_Val;//指定将要加载到捕获比较寄存器的脉冲值,当计数器计数到这个值时,电平发生跳变
		TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较极性,当定时器计数值小于CCR1_Val时为高电平
		TIM_OC1Init(TIM3, &TIM_OCInitStructure);
		TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
		/* PWM1 Mode configuration: Channel2 */
	
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
	
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);
	
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel3 */
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
//指定将要加载到捕获比较寄存器的脉冲值,当计数器计数到这个值时,电平发生跳变
  TIM_OC3Init(TIM3, &TIM_OCInitStructure);
	TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel4 */
	
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
//指定将要加载到捕获比较寄存器的脉冲值,当计数器计数到这个值时,电平发生跳变
	TIM_OC4Init(TIM3, &TIM_OCInitStructure);
	TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM3, ENABLE);
	
	TIM_Cmd(TIM3, ENABLE);/* TIM3 enable counter */

 while (1)
 {}
 }

 void RCC_Configuration(void)
 {
 /* TIM3 clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOA and GPIOB clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);

 }
	 void GPIO_Configuration(void)
 {
				 
			GPIO_InitTypeDef GPIO_InitStructure;
			/* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */
			GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // PA6===TIM3_Ch1, PA7===TIM3_Ch2
			GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
			GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO_Init(GPIOA, &GPIO_InitStructure);
			GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; // PB0===TIM3_Ch3, PB1===TIM3_Ch4
			GPIO_Init(GPIOB, &GPIO_InitStructure);
}

SysTic定时

#include "stm32f10x.h"

__IO uint32_t TimingDelay; //声明外部变量

void RCC_Configuration(void); 
void SysTick_Configuration(void);
void NVIC_Configuration(void); 
void GPIO_Configuration(void); 

void delay_ms(__IO uint32_t nTime);

int main(void)
{ 
	RCC_Configuration();//配置时钟
	GPIO_Configuration(); // 要先配置管脚在配置
	SysTick_Configuration();
	NVIC_Configuration();
	
	GPIO_ResetBits(GPIOA,GPIO_Pin_8);
	
	while(1)
	{
		delay_ms(500);
		GPIOA->ODR^=GPIO_Pin_8; 
	}
}


void RCC_Configuration(void)
{
	SystemInit(); //72MHz
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能TIM7的时钟
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void NVIC_Configuration(void)
{ 
	NVIC_InitTypeDef NVIC_InitStructure;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitStructure.NVIC_IRQChannel = SysTick_IRQn;//设置SysTic中断
	//TIM3_IRQn; ;// @设置TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 中断使能
	NVIC_Init(&NVIC_InitStructure);
}

void SysTick_Configuration(void)
{
	SysTick->LOAD = 72000 - 1; //设置1ms重装值
	SysTick->CTRL = 0x00000007;  // 选用HCLK为中断源
}


void delay_ms(__IO uint32_t nTime) 
{
	TimingDelay = nTime;
	while(TimingDelay != 0) 
	{};
}

extern __IO uint32_t TimingDelay;

void SysTick_Handler(void) //SysTick中断处理子程序
{
	if (TimingDelay != 0x00)
	{
		TimingDelay--;
	}
}


16、CMSIS RTOS

/*----------------------------------------------------------------------------
 * CMSIS-RTOS 'main' function template
 *---------------------------------------------------------------------------*/

#include "stm32f10x.h"

#define osObjectsPublic                     // define objects in main module
#include "osObjects.h"                      // RTOS object definitions
/*
 * main: initialize and start the system
 */
 
#define ON 1
#define OFF 0
#define LED1(opt) ((opt) ? (GPIOA->BRR |= 1 << 8) : (GPIOA->BSRR |= 1 << 8))
#define LED2(opt) ((opt) ? (GPIOD->BRR |= 1 << 2) : (GPIOD->BSRR |= 1 << 2))
 
void LED_Init(void)
{
	RCC->APB2ENR |= (1 << 2) | (1 << 5);
	GPIOA->CRH &= 0xFFFFFFF0;
	GPIOA->CRH |= 0x00000003; // PA8设置为推挽输出
	
	GPIOD->CRL &= 0xFFFFF0FF;
	GPIOD->CRL |= 0x00000300; //PD2设置为推挽输出
	
	LED1(OFF);
	LED2(OFF); // 关闭两个灯
	
}
 
void led_Thread1(void const *p_arg)
{
	while(1)
	{
		LED1(ON);
		osDelay(500);
		LED1(OFF);
		osDelay(500);
	}
}

void led_Thread2(void const *p_arg)
{
	for(;;)
	{
		LED2(OFF);
		osDelay(500);
		LED2(ON);
		osDelay(500);
		
	}
}

osThreadDef(led_Thread1, osPriorityNormal, 1, 0); // 定义线程1
osThreadDef(led_Thread2, osPriorityNormal, 1, 0); // 定义线程2
 
osThreadId T_led_ID1; //线程1的Id
osThreadId T_led_ID2; //线程2的Id

int main (void) {
  osKernelInitialize ();                    // initialize CMSIS-RTOS

  // initialize peripherals here
	LED_Init();
  // create 'thread' functions that start executing,
  // example: tid_name = osThreadCreate (osThread(name), NULL);
	T_led_ID1 = osThreadCreate(osThread(led_Thread1), NULL); // 线程1
	T_led_ID2 = osThreadCreate(osThread(led_Thread2), NULL); // 线程2
	
  osKernelStart ();                         // start thread execution 
}



END(嵌入式课程结束)接下来自己走咯,之后的学习记录会重新开贴写

复制了一个学期的代码,再自己修修改改,大概就汇聚在这个上面。

上面几乎所有的类型都囊括了,以后读别人代码的时候,这些基础库函数初始化代码,就是支持我的修改的基石咯

接下来我的学习计划就是把硬件知识提高上来,能读得懂别人的代码,然后利用原子哥的资源,网络上的的各种代码,修修补补,改出自己想要的代码,自己想要的结果,至少我觉得,我现在走的路都是前人走过了,我写的代码也都是前人已经写过的,并且已经开源的,现在能读得懂,并且能改的出自己想要的结果,这个就是我当前很长一段时间的目标,等到了能自己写代码,让人阅读的时候,那我这篇博客的点击量一定会很高吧,毕竟这是大神菜鸡的时候,

哈哈,现在我是真的菜,还是那种没有本事却很跳的那种,不知道以后我回过头来看,我成长的痕迹,看我现在写下的所记录的东西,不知道那时,时间有没有磨平我的棱角,不知道我有没有实现最初的梦想,愿初心不忘,归来仍是少年!



                                                                                                                           齐鲁工业大学,机电楼A511

                                                                                                                            2018年6月5日 19:18:02

                                                        


  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值