栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【嵌入式原理与应用】南航嵌入式——实验例程

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【嵌入式原理与应用】南航嵌入式——实验例程

实验例子-代码 GPIO实验 例1:GPIO-MOTO实验

​ 当按下KEY1键时,双色红灯闪烁且电机正转,当按下当KEY2键时,双色绿灯闪烁且电机反转,当按下KEY3键时,双色灯灭,电机停止。

#include "stm32f10x_conf.h"

#define KEY1    GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11)
#define KEY2    GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_12)
#define KEY3    GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)
#define IA(x)    ((x) ? (GPIO_SetBits(GPIOB, GPIO_Pin_8)) : (GPIO_ResetBits(GPIOB, GPIO_Pin_8)))
#define IB(x)    ((x) ? (GPIO_SetBits(GPIOB, GPIO_Pin_9)) : (GPIO_ResetBits(GPIOB, GPIO_Pin_9)))
#define LEDR(x)   ((x) ? (GPIO_SetBits(GPIOB, GPIO_Pin_1)) : (GPIO_ResetBits(GPIOB, GPIO_Pin_1)))
#define LEDG(x)   ((x) ? (GPIO_SetBits(GPIOB, GPIO_Pin_2)) : (GPIO_ResetBits(GPIOB, GPIO_Pin_2)))


void Delayms(uint16_t N)
{
    uint32_t i;
    for (i = 0; i < (8000 * N); i++);
}


void GPIO_MOTO_Init(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOD, &GPIO_InitStructure);  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOC, &GPIO_InitStructure);  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);  

    
    IA(0);
    IB(0);                    
    LEDR(0);
    LEDG(0);            
    GPIO_SetBits(GPIOD, GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_7);
}

#define  n 200    

int main(void) {
    u8 KEY = 0;
    SystemInit();            
    GPIO_MOTO_Init();            
    while (1) 
    {
        if (KEY1 == 0) KEY = 1;
        if (KEY2 == 0) KEY = 2;
        if (KEY3 == 0) KEY = 3;
        switch (KEY)
        {
            case 1:        
                IA(1);            
                IB(0);            
                LEDR(1);        
                Delayms(n);
                LEDR(0);
                Delayms(n);
                LEDG(0);        
                break;
            case 2:        
                IA(0);            
                IB(1);            
                LEDR(0);        
                LEDG(1);        
                Delayms(n);
                LEDG(0);
                Delayms(n);
                break;
            case 3:        
                IA(0);            
                IB(0);            
                LEDR(0);        
                LEDG(0);        
                break;
        }
    }
}
										 
例2:GPIO简单交互

​ 当按KEY1(PD11)键时,让LED1(PD2)闪烁;当按KEY2(PD12)键时,让LED2(PD3)闪烁;当按KEY3(PC13)键时,让LED3(PD4)闪烁;当按KEY4(PA0)键时,让LED4(PD7)闪烁;当同时按下KEY1和KEY2时,四个LED发光管全亮。

#define LED1(x) ((x)? GPIO_SetBits(GPIOD,(1<<2)) : GPIO_ResetBits(GPIOD,(1<<2)))
#define LED2(x) ((x)? GPIO_SetBits(GPIOD,(1<<3)) : GPIO_ResetBits(GPIOD,(1<<3)))
#define LED3(x) ((x)? GPIO_SetBits(GPIOD,(1<<4)) : GPIO_ResetBits(GPIOD,(1<<4)))
#define LED4(x) ((x)? GPIO_SetBits(GPIOD,(1<<7)) : GPIO_ResetBits(GPIOD,(1<<7)))

#define KEY1 (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11))
#define KEY2 (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_12))
#define KEY3 (GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13))
#define KEY4 (GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0))

unit16_t key = 0;

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE); 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3  | GPIO_Pin_4  | GPIO_Pin_7 ; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_Init(GPIOD, &GPIO_InitStructure);
    
   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
	LED1(1);
	LED2(1);
	LED3(1);
	LED4(1);		
}

void main()
{
	SystemInit();
	GPIO_Configuration();
	while(1)
	{
		if(KEY1 == 0) key = 1;
		if(KEY2 == 0) key = 2;
		if(KEY3 == 0) key = 3;
		if(KEY4 == 0) key = 4;
		if(KEY1 == 0 && KEY2 == 0) key = 5;
		
		switch(key)
		{
			case 1:
				LED2(1); LED3(1); LED4(1);
				LED1(1); Delay(); LED1(0); break;
			case 2:
				LED1(1); LED3(1); LED4(1);
				LED2(1); Delay(); LED2(0); break;
			case 3:
				LED1(1); LED2(1); LED4(1);
				LED3(1); Delay(); LED3(0); break;
			case 4:
				LED2(1); LED3(1); LED4(1);
				LED1(1); Delay(); LED1(0); break;
			case 5:
				LED1(0); LED2(0); LED3(0); LED4(0);
			    break;
			default:
				LED1(1); LED2(1); LED3(1); LED4(1);
				break;
		}
	}
}
例3:GPIO 引脚中断

​ 采用中断方式判断单个按键:当按下KEY1(PD11)时,让LED1(PD2)闪烁;当按下KEY2(PD12)时让LED2(PD3)闪烁;采用查询方式判断复合键:当同时按下KEY1和KEY2时,LED1和LED2发光管全灭。

#define LED1(x) ((x)? GPIO_SetBits(GPIOD,(1<<2)) : GPIO_ResetBits(GPIOD,(1<<2)))
#define LED2(x) ((x)? GPIO_SetBits(GPIOD,(1<<3)) : GPIO_ResetBits(GPIOD,(1<<3)))

#define KEY1 (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11))
#define KEY2 (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_12))

unit16_t Flag = 0;

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE); 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 ; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOD , GPIO_PinSource11);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOD , GPIO_PinSource12);
	
	
	LED1(1);
	LED2(1);		
}

void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	     
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn ; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;	  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE ;	
	NVIC_Init(&NVIC_InitStructure);
}

void EXTI_Configuration(void)
{
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line11;  	
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;	
	EXTI_InitStructure.EXTI_LineCmd	= ENABLE;
	EXTI_Init(&EXTI_InitStructure);	
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line12;  
	EXTI_Init(&EXTI_InitStructure);	
}

void EXTI15_10_IRQHandler() 
{
	if(EXTI_GetITStatus(EXTI_Line11) != RESET)
	{
		Flag = 0x01;
		EXTI_ClearITPendingBit(EXTI_Line11);
	} 
	else if(EXTI_GetITStatus(EXTI_Line12) != RESET)
	     {
		    Flag = 0x2;
		    EXTI_ClearITPendingBit(EXTI_Line12);
	     }
}


int main()
{
	SytemInit();
	GPIO_Configuration();
	NVIC_Configuration();
	EXTI_Configuration();
	while(1)
	{
		if(KEY1 == 0 && KEY2 == 0)
		{
			Flag = 0x03;
		}
		
		switch(Flag)
		{
			case 0x01:
				LED2(1);
				LED1(0); Delay(); LED1(1); Delay();
				break;
			case 0x02:
				LED1(1); 
				LED2(0); Delay(); LED2(1); Delay();
				break;
			case 0x03:
				LED1(1); LED2(1);
				break;
			default:
				LED1(0); LED2(0);
				break;
		}
	}
}
TIM实验 例1:TIM更新方式定时

​ 定时器TIM1定时1秒,TIM2定时500ms,TIM3定时200ms,定时器到时分别使LED1、LED2和LED3改变状态(闪烁)

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
	GPIO_InitStructure.GPIO_Pin = LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = LED5_PIN;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = BEEP_PIN ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	LED1(1);
	LED2(1);
	LED3(1);
	LED4(1);
			
}
void NVIC_Configuration(void)
{
	
	NVIC_InitTypeDef NVIC_InitStructure;
	
	
	NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
}

void TIM_Configuration(void)
{

	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
							 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM3, ENABLE);

	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0	;
	
	TIM_TimeBaseStructure.TIM_Period = 10*1000-1; //1000ms
	TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/10000-1;//0;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

	
	TIM_TimeBaseStructure.TIM_Period = 10*500-1; //500ms
	TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/10000-1;//0;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;	
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

	
	TIM_TimeBaseStructure.TIM_Period = 10*200-1; //200ms
	TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/10000-1;//0;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	
	
	TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	
	TIM_Cmd(TIM1, ENABLE);
	TIM_Cmd(TIM2, ENABLE);
	TIM_Cmd(TIM3, ENABLE);
}

u8 TP1=0,TP2=0,TP3=0;

void TIM1_UP_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)  
	{
		TIM_ClearITPendingBit(TIM1, TIM_IT_Update);       
		TP1++;
		if (TP1&1) 			GPIO_ResetBits(GPIOD,GPIO_Pin_2);   
		else 				GPIO_SetBits(GPIOD,GPIO_Pin_2); 		
	}
}
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) 	
	{
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update); 			
		TP2++;
		if (TP2&1) 			GPIO_ResetBits(GPIOD,GPIO_Pin_3);   
		else 				GPIO_SetBits(GPIOD,GPIO_Pin_3); 		
	}
}
void TIM3_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);       
		TP3++;
		if (TP3&1) 			GPIO_ResetBits(GPIOD,GPIO_Pin_4);   
		else 				GPIO_SetBits(GPIOD,GPIO_Pin_4); 		
	}
}

int main(void)
{
	SystemInit();
	GPIO_Configuration();
	TIM_Configuration();         			
	NVIC_Configuration();	
	LCD_Init();												
	Welcome(); 										 		
	LED1(1);LED2(1);LED3(1);LED4(1);
	while(1)
	{		
		
	}
}
例2:TIM比较定时

​ 定时器TIM3利用比较器1定时1秒让LED1闪烁,比较器2定时500ms,让LED2闪烁,比较器3定时200ms,让LED3闪烁,比较器4定时100ms让LED4闪烁

u16 CCR1_Val = 10*1000;	
u16 CCR2_Val = 10*500;	
u16 CCR3_Val = 10*200;	
u16 CCR4_Val = 10*100;	

void TIM_Configuration(void)
{

	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
								 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	TIM_TimeBaseStructure.TIM_Period =65535;
	TIM_TimeBaseStructure.TIM_Prescaler =(SystemCoreClock/10000)-1;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
		
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;						
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
	TIM_OCInitStructure.TIM_Pulse = CCR1_Val;											
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);
	
	
	
	TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);
	
	
	TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
	TIM_OC3Init(TIM3, &TIM_OCInitStructure);
	
	//TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
	TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
	TIM_OC4Init(TIM3, &TIM_OCInitStructure);
	
	
	
	
	TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 |TIM_IT_CC4, ENABLE);
	
	
	TIM_Cmd(TIM3, ENABLE);
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
	GPIO_InitStructure.GPIO_Pin = LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = LED5_PIN;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = BEEP_PIN ;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	
	LED1(1);
	LED2(1);
	LED3(1);
	LED4(1);
			
}

void NVIC_Configuration(void)
{
	
	NVIC_InitTypeDef NVIC_InitStructure;
	
	
	NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
}

extern u16 CCR1_Val;
extern u16 CCR2_Val;
extern u16 CCR3_Val;
extern u16 CCR4_Val;

void TIM3_IRQHandler(void)
{
	uint16_t capture = 0;
	if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);		
		
   			GPIOD->ODR ^= 1<<2;											
		capture = TIM_GetCapture1(TIM3);						
		TIM_SetCompare1(TIM3, capture + CCR1_Val);	
	}
	else if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
		
   			GPIOD->ODR ^= 1<<3;	
		capture = TIM_GetCapture2(TIM3);
		TIM_SetCompare2(TIM3, capture + CCR2_Val);
	}
	else if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
		
   			GPIOD->ODR ^= 1<<4;	
		capture = TIM_GetCapture3(TIM3);
		TIM_SetCompare3(TIM3, capture + CCR3_Val);						   
	}
	else if (TIM_GetITStatus(TIM3, TIM_IT_CC4) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC4);
		
   			GPIOD->ODR ^= 1<<7;	
		capture = TIM_GetCapture4(TIM3);
		TIM_SetCompare4(TIM3, capture + CCR4_Val);						   
	}
	
}

int main(void)
{
	SystemInit();
	GPIO_Configuration();
	TIM_Configuration();         			
	NVIC_Configuration();	
	LCD_Init();												
	Welcome(); 										 		
	LED1(1);LED2(1);LED3(1);LED4(1);
	while(1)
	{		
		
	}
}
例3:输出PWM波

​ 运行程序后PWM输出频率10kHz,起始占空比50%

void Init_TIMER(void)
{
	TIM_TimeBaseInitTypeDef	 TIM_BaseInitStructure;				//定义一个定时器结构体变量
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);  //使能定时器4,重要!!
	TIM_DeInit(TIM4);                              				//将IM2定时器初始化位复位值
	TIM_InternalClockConfig(TIM4); 												//配置 TIM4 内部时	   
	TIM_BaseInitStructure.TIM_Period = 7200-1; 						//设置自动重载寄存器值为最大值	0~65535之间  7200/72000000=1/10000s=0.1ms即10KHz													
															//TIM_Period(TIM1_ARR)=7200,计数器向上计数到7200后产生更新事件,
															//计数值归零 也就是 1ms产生更新事件一次
	TIM_BaseInitStructure.TIM_Prescaler = 0;  				//自定义预分频系数为0,即定时器的时钟频率为72M提供给定时器的时钟	0~65535之间
															//设置预分频器分频系数0
	TIM_BaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分割为0
	TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;   
															//TIM向上计数模式 从0开始向上计数,计数到1000后产生更新事件
	TIM_TimeBaseInit(TIM4, &TIM_BaseInitStructure); 		//根据指定参数初始化TIM时间基数寄存器	
      
 	TIM_ARRPreloadConfig(TIM4, ENABLE);						//使能TIMx在 ARR 上的预装载寄存器 

	TIM_Cmd(TIM4, ENABLE); 		          //使能TIM4
}

void Init_PWM(uint16_t Dutyfactor)
{
	TIM_OCInitTypeDef  TIM_OCInitStructure;					//定义一个通道输出结构

	TIM_OCStructInit(&TIM_OCInitStructure);					//设置缺省值

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;	   	//PWM 模式 1 输出 	
	TIM_OCInitStructure.TIM_Pulse = Dutyfactor; 			//设置占空比,占空比=(CCRx/ARR)*100%或(TIM_Pulse/TIM_Period)*100%
															  
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM 输出比较极性高   
																    
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;    	//使能输出状态  需要PWM输出才需要这行代码
														
  TIM_OC3Init(TIM4, &TIM_OCInitStructure);				//根据参数初始化PWM寄存器 通道3(PB8)   

	TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);//使能 TIMx在 CCR3 上的预装载寄存器

  TIM_CtrlPWMOutputs(TIM4,ENABLE);  							//设置TIM4 的PWM 输出为使能  
}

void PWM_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;					//定义一个GPIO结构体变量

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);	
																								//使能各个端口时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8| GPIO_Pin_9; //PB8和PB9引脚,PB6、PB7、PB8和PB9分别为TIM4对应的CH1、CH2、CH3和CH4四个通道的PWM输出引脚,这里使用PB8和PB9
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	   	  //复用输出推挽
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	   	//配置端口速度为50M
	GPIO_Init(GPIOB, &GPIO_InitStructure);				   			//将端口GPIOD进行初始化配置
}

int main(void)
 {	
	 
	uint16_t Pulse=7200*0.5;				//占空比为50%  周期7200(1ms)
	SystemInit();
	PWM_GPIO_Init();		    		//PWM输出口PB8,初始化
	Init_TIMER();								//定时器4初始化
	Init_PWM(Pulse);			  //PWM的通道3初始化设置	
	GPIO_Configuration();
	TIM2_Cap_Init(0xffff,72-1);					
	LCD_Init();													
	Welcome(); 										 			
	LED1(1);LED2(1);LED3(1);LED4(1);
	while(1)
	{		
 		if(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_11)==0)   //KEY1按下
		{
			Pulse+=100;									   //占空比加100
			if(Pulse>=7200-1) Pulse=1;
			TIM_SetCompare3(TIM4,Pulse);                   //写入定时器4的通道3的占空比值
		}
	
		
		if(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_12)==0)   //KEY2按下
		{
			Pulse-=100;									   //占空比减100
			if((Pulse<1)||(Pulse>7200))   Pulse=7200-1;
			TIM_SetCompare3(TIM4,Pulse);                   //写入定时器4的通道3的占空比值
		}
			Delay_ms(100);
			LCD_ShowNum(80,190,Pulse,8,16);		
			LCD_ShowNum(80,230,Pulse*100/7200,8,16);	

	}
}
例4:按键时长判断

​ 利用定时计数器TIM3定时 10ms,每当 10ms 中断一次,在中断服务程序中判断按键,当按键按下超过 0.5 秒小于 1 秒时称为短按,按下超过 3 秒时为长按。

试用 C 语言写出定时器 TIM3定时 10ms 的初始化函数:

(1)当短按奇数次按键时,让 LED 发光,短按偶数按键时,让 LED 熄灭;

(2)长按偶数次按键时让蜂鸣器发声报警,长按奇数次按键时停止发声。

void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_SetVecorTable(NVIC_VecTab_FLASH,0x0000);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC, ENABLE); 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	
	
	LED1(1);		
}

void TIM_Configuration(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	TIM_TimeBaseStructure.TIM_Period=10*10-1;
	TIM_TimeBaseStructure.TIM_Prescaler=SystemCoreClock/10000-1;
	TIM_TimeBaseStructure.TIM_ClockDivision=0;
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
	TIM_Cmd(TIM3,ENABLE);
}

#define ShortKeyConst 50
#define LongKeyConst 300

u32 TP1=0, TP2=0, Times;

void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update)!=RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
		if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11) == 0) Times++;
		else{
			if(Times >= LongKeyConst)
			{
				TP1++;
				if(TP1&1 == 1) GPIO_SetBits(GPIOC,GPIO_Pin_0);
				else GPIO_ResetBits(GPIOC,GPIO_Pin_4);
			}
			else if((Times >= ShortKeyConst) && (Times <= ShortKeyConst*2))
				 {
					TP2++;
					if(TP2&1 == 1) GPIO_SetBits(GPIOD,GPIO_Pin_2);
					else GPIO_ResetBits(GPIOD,GPIO_Pin_2);
				 }
			Times = 0; 
		}
	}
}

int main(void)
{
	SystemInit();
	GPIO_Configuration();
	TIM_Configuration();
	NVIC_Configuration();
	LCD_Init();
	Welcome();
	LED1(1);LED2(1);LED(3);LED(4);
	while(1)
	{
		
	}
} 
模拟输入输出系统设计 例1:ADC应用

​ 对于 STM32F10x 微控制器,使用片上 ADC 通道 3(PA3 作为 ADCIN3)作为电位器位置检测的一个实例,如图 7.41 所示。当旋转电位器 VR1 时,ADCIN3 随之电压发生变化,如果电位代表位置,假设 0V表示位置 0 米,3.3V 表示 100 米,当电位器从最低端向最高端旋转时,电位从 0 到 3.3V 变化,也即位置从 0 到 100 米线性变化。试回答:

(1)写出对片上 DAC 的初始化程序片段(含引脚配置及 DAC 初始化)。

(2)写出采集电位并进行标度变换的程序。

void ADC_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_ADC1,ENABLE);		
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;	                    	
	GPIO_Init(GPIOA, &GPIO_InitStructure);

			
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	                
	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_InitStructure.ADC_NbrOfChannel = 1; 
	ADC_Init(ADC1, &ADC_InitStructure);
	
	ADC_Cmd(ADC1, ENABLE);	                     
	ADC_ResetCalibration(ADC1);	                 
	while(ADC_GetResetCalibrationStatus(ADC1));	 
	ADC_StartCalibration(ADC1);			         		 
	while(ADC_GetCalibrationStatus(ADC1));	     
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		 	 
}

int Read_ADC1_MultiChannel(u8 channNo)
{  
	u16  ADC_data;
    ADC_RegularChannelConfig(ADC1, channNo, 1, ADC_SampleTime_239Cycles5 );
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		 		
    while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));	
    ADC_data=ADC_GetConversionValue(ADC1);  		  
    ADC_SoftwareStartConvCmd(ADC1, DISABLE);	 		
return(ADC_data);                                                                     
} 

int main()
{
	int value = 0;
	int voltage = 0; 
	int dis = 0;
	ADC_Configuration ();
	while(1)
	{
		value = Read_ADC1_MutiChannel(ADC_Channel_3);
		voltage = (3300*value)/4095;  // 标度转换后的电压值,单位mv 
		dis = (100*value)/4095;    // 标度转换后的距离 
	}
} 
例2:ADC_DAC应用

​ 试设计一个模拟输入输出系统,采用 STM32F10x 微控制器,采用 3.3V 供电,内置 12 位 ADC,某压力传感器输出 0-100mV 对于 0-10Mpa,压力超过 8.5Mpa 时,输出报警信号,让蜂鸣器发声,低于 8Mpa时解除报警。并将得到的压力用 4-20mA 电流输出到外部。写出相关程序片段。

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	GPIO_ResetBit(GPIOC,GPIO_Pin_0);  // 初始化蜂鸣器不响		
}

void ADC_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_ADC1,ENABLE);		
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;	                    	
	GPIO_Init(GPIOA, &GPIO_InitStructure);

			
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	                
	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_InitStructure.ADC_NbrOfChannel = 1; 
	ADC_Init(ADC1, &ADC_InitStructure);
	
	ADC_Cmd(ADC1, ENABLE);	                     
	ADC_ResetCalibration(ADC1);	                 
	while(ADC_GetResetCalibrationStatus(ADC1));	 
	ADC_StartCalibration(ADC1);			         		 
	while(ADC_GetCalibrationStatus(ADC1));	     
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		 	 
}

void DAC_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitType;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE );	 //使能PORTA通道时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );	  //使能DAC通道时钟 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;				 // 端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 		 //复用推挽(模拟)输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	DAC_DeInit();
	
	DAC_InitType.DAC_Trigger=DAC_Trigger_None;	//不使用触发功能   DAC_Trigger_T3_TRGO 定时器为触发源 
	DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	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, 0x0);  //12位右对齐数据格式设置DAC初始值,输出0
}

int Read_ADC1_MultiChannel(u8 channNo)
{  
	u16  ADC_data;
    ADC_RegularChannelConfig(ADC1, channNo, 1, ADC_SampleTime_239Cycles5 );
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		 		
    while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));	
    ADC_data=ADC_GetConversionValue(ADC1);  		  
    ADC_SoftwareStartConvCmd(ADC1, DISABLE);	 		
	return(ADC_data);                                                                     
} 

int main()
{
   int high = 4095 * 8.5 / 10;
   int low = 4095 * 8.0 / 10;
   int Din
   SystemInit();
   GPIO_Configuration();
   ADC_Configuration();
   DAC_Configuration();
   while(1)
   {
   	   Din = Read_ADC1_MultiChannel(ADC_Channel_1);
   	   if(Din > high) GPIO_SetBit(GPIOC, GPIO_Pin_0); // 报警 
   	   else if(Din < low) GPIO_ReSetbits(GPIOC, GPIO_Pin_0); // 解除报警
	
	   Dout = 496 + (1986 * Din) / 4095;
	   DAC_SetChannel1Data(DAC_Align_12b_R, Dout); // 输出电流 
   } 	
}
例3:ADC_DMA应用
void GPIO_Configuration()
{ // 将用到的引脚配置为模拟输入模式
    GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);		
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7;   
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;	              
	GPIO_Init(GPIOA, &GPIO_InitStructure);	
}

void DMA_Congiguration(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA1时钟
	
	DMA_DeInit(DMA1_Channel1);  //指定DMA通道
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR_Address;//设置DMA外设地址ADC_DR_Adress
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;	//设置DMA内存地址,ADC转换结果直接放入该地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设为设置为数据传输的来源
    DMA_InitStructure.DMA_BufferSize = SampleNum*ChannelNum;	//DMA缓冲区设置
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//DMA不允许地址递增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);	
    DMA_Cmd(DMA1_Channel1, ENABLE);  //使能DMA通道
}

void ADC_Configuration(void)
{
  DMA_Congiguration();    // ADC的DMA初始化 
  
  ADC_InitTypeDef ADC_InitStructure;	
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//使能ADC1时钟
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //使用独立模式
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;			 //扫描模式允许,多通道必须使能
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连接转换模式,无需外接触发器
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不用外部触发
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //使用数据右对齐
  ADC_InitStructure.ADC_NbrOfChannel = ChannelNum;  // ChannelNum个通道转换通道
  ADC_Init(ADC1, &ADC_InitStructure);

  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_55Cycles5); //通道3(电位器)采样周期55.5个时钟周期
  ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 2, ADC_SampleTime_55Cycles5); //通道6(PT100)采样周期55.5个时钟周期
  ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 3, ADC_SampleTime_55Cycles5); //通道7(电流电压)采样周期55.5个时钟周期
  ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 4, ADC_SampleTime_55Cycles5); //通道16(内部温度)采样周期55.5个时钟周期
  ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 5, ADC_SampleTime_55Cycles5); //通道17(基准电压)采样周期55.5个时钟周期

  ADC_DMACmd(ADC1, ENABLE);	 //使能ADC的DMA
  ADC_Cmd(ADC1, ENABLE); //使能ADC1
  ADC_TempSensorVrefintCmd(ENABLE);			 					 	

  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));
  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);  //开始转换
}

int ReadADCAverageValue(uint16_t Channel)  //求平均值
{
 	u8 i;
 	u32 sum = 0;
 	for(i=0; i
  		sum+=ADC_ConvertedValue[i][Channel];
 	}
 	return (sum/SampleNum);
}

int main()
{
   SystemInit();
   GPIO_Configuration();
   ADC_Configuration();
   while(1)
   {
   	   int value0 =  ReadADCAverageValue(0);
   	   int value1 =  ReadADCAverageValue(1);
   	   int value2 =  ReadADCAverageValue(2);
   	   int value3 =  ReadADCAverageValue(3);
   	   int value4 =  ReadADCAverageValue(4);
   	   // ......
   }
} 
例4:DAC输出频率为f的正弦波
int index = 0;

const uint16_t Sine12bit[32] = {2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4096, 4056,
								3939, 3750, 3459, 3185, 2831, 2447, 2047, 1647, 1263, 909,
								599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};
								
void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_SetVecorTable(NVIC_VecTab_FLASH,0x0000);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

void TIM_Configuration(uint16_t f)
{
	TIM_TimeBaseInitTypeDef	TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 ,ENABLE);
	TIM_DeInit(TIM3);
	TIM_TimeBaseStructure.TIM_Period = SystemCoreClock/1/32/f-1;//一个周期32个点,两间隔离时间的倒数即频率,改变这个值能改变正弦波的频率 反比例变化    
	TIM_TimeBaseStructure.TIM_Prescaler = 0x0;       //这个值要为零 否则无输出   	 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;   //这个值要为零 否则无输出
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);	
	TIM_Cmd(TIM3, ENABLE);	   //使能TIM3
}

void DAC_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitType;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE );	  //使能PORTA通道时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );	  //使能DAC通道时钟 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;				 // 端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 		 //复用推挽(模拟)输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	DAC_DeInit();
	
	DAC_InitType.DAC_Trigger=DAC_Trigger_None;	//不使用触发功能   
	DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_None;//不使用波形发生
	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, 0x0);  //12位右对齐数据格式设置DAC初始值,输出0
}

void TIM3_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);       
	    DAC_SetChannel1Data(DAC_Align_12b_R, uint16_t Sine12bit[index++]);
	    if(index >= 32) index = 0;
	}
}

int main()
{
	NVIC_Configuration();
	TIM_Configuration(f);
	DAC_Configuration();
	// ......
}
例5:DAC_DMA输出乐曲
uint32_t DAC_DHR12R2_Address = 0x40007414;	  //0x4000 7400 - 0x4000 77FF为DAC地址范围,其中0x40007414为DAC2右对齐数据保持寄存器
const uint16_t Sine12bit[32] = {   
                      2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
                      3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909, 
                      599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};

uint32_t DAC2Sine12bit[32];
const uint16_t Redfrebit[]={......}  //存放音乐的频率 
void TIM_Configuration(uint16_t f)
{
	TIM_TimeBaseInitTypeDef	TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 ,ENABLE);
	TIM_DeInit(TIM3);
	TIM_TimeBaseStructure.TIM_Period = SystemCoreClock/1/32/f-1;//一个周期32个点,两间隔离时间的倒数即频率,改变这个值能改变正弦波的频率 反比例变化    
	TIM_TimeBaseStructure.TIM_Prescaler = 0x0;       //这个值要为零 否则无输出   	 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;   //这个值要为零 否则无输出
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	
	TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);  //使用更新事件作为触发输出	
	TIM_Cmd(TIM3, ENABLE);	   //使能TIM3
}

void DAC_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC ,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);		   

	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	 //PA5:DAC2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA ,&GPIO_InitStructure);
	DAC_DeInit();									  //还原到初始状态

	
	DAC_InitStructure.DAC_Trigger = DAC_Trigger_T3_TRGO;	//选择定时器3作外部触发源
	DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;	   //自定义波形产生
	DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;	   //失能输出缓冲
	DAC_Init(DAC_Channel_2, &DAC_InitStructure);					   //DAC初始化
	DAC_Cmd(DAC_Channel_2,  ENABLE);								   //使能DAC
	DAC_SoftwareTriggerCmd(DAC_Channel_2, ENABLE);					   //通道2由软件触发	
}

void DMA_Configuration(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2 ,ENABLE);				 //打开DMA2时钟
	DMA_DeInit(DMA2_Channel4);								         //将DMA通道4 的寄存器设为默认值
	DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R2_Address;	 //DAC2  12位右对齐数据寄存器地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DAC2Sine12bit; //待送入DAC2的数字量
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;				 //外设作为数据传输的来源
	DMA_InitStructure.DMA_BufferSize = 32;						     //DMA缓存大小,32个数据(一个周期的正弦波点数)
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设寄存器地址不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;			 //内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设为16位(12位DAC)
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//内存数据宽度采用16位模式,对应DAC12位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;			 //工作在循环缓存模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;		 //设置DMA通道优先级为高
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;			 //不设置为内存到内存传输

	DMA_Init(DMA2_Channel4, &DMA_InitStructure);
	DMA_Cmd(DMA2_Channel4, ENABLE);		   

	
	DAC_Cmd(DAC_Channel_2, ENABLE);
	DAC_DMACmd(DAC_Channel_2, ENABLE);		 //使能DAC通道2的DMA
}

int main()
{
	SystemInit();
	DAC_Configuration();
	DMA_Configuration();
	for (int Idx = 0; Idx < 32; Idx++)
	{
		DAC2Sine12bit[Idx] = (Sine12bit[Idx] << 16) + (Sine12bit[Idx]);	//将正弦波离散点装入指定DAC2Sine12bit[]中(DMA指定的外设地址)
	}
	
	while(1)
	{			
		if (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11)==0) KEY=1; // 按键1播放 
		else if (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_12)==0) KEY=2; // 按键2停止 
				
		switch (KEY)
		{		
		    case 1:
		        for (i=0;i<68;i++)
			    {
		           if (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_12)==0) 
				   {    
				       KEY=2;
					   TIM_Cmd(TIM3, DISABLE);
					   break;
					}		
		           TIM_Configuration(Redfrebit[i]);	   	//TIM2赋值改变频率,发不同音调
		           Delay_ms(300);
			    }
			    break;				
		    case 2:
	             TIM_Cmd(TIM3, DISABLE);	//不使能定时器(不让DAC输出)
		        Delay_ms(300);
			   break;
		}		
    }
}
互连通信接口设计 例1:USART初始化程序
#define U1Baud   115200
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

PUTCHAR_PROTOTYPE
{
	USART_SendData(USART1, (uint8_t) ch);   
	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
	return ch;
}  // 定义之后,可以使用printf 

int flag = 0;

void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);			  //中断分组2
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 		  //USART1接收中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		  //次占优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;	
	NVIC_Init(&NVIC_InitStructure);

	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; 		  //USART2接收中断
	NVIC_Init(&NVIC_InitStructure);

}

void USART_Configuration(uint32_t UART1_Baud)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD 
						   |RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO, ENABLE);

  
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9 ;
	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_10 ;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
      	
    
	USART_InitStructure.USART_BaudRate = UART1_Baud;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

	USART_Init(USART1, &USART_InitStructure);
	USART_Cmd(USART1, ENABLE);

	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);		
}

void USART1_SendString(uint8_t *ch)
{
	while(*ch!=0)
	{		
		USART_SendData(USART1, *ch);
		while(!USART_GetFlagStatus(USART1, USART_FLAG_TXE));
		ch++;
	}   	
}

void USART1_IRQHandler(void)
{
	char res;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
	{
        USART_ClearFlag(USART1, USART_IT_RXNE);		
	    res =USART_ReceiveData(USART1);		       // 读取接收到的数据USART1->DR
	    USART1_SendString("rn 接收到的字符是");
		while(!USART_GetFlagStatus(USART1, USART_FLAG_TXE));
		USART_SendData(USART1, res);
		flag = 1;
	}  	
}

int main()
{
	SystemInit();
	NVIC_Configuration();
	USART_Configuration(U1Baud);
	//...... 
}
嵌入式应用系统设计实例
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/934864.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号