• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

stm8单片机--学好高端单片机stm32和DSP的转折点

        单片机对于工程师来说是必备的一种知识,对于硬件工程师也是一样。但是大多数人了解的大多是51单片机,因为它基础,简单,是个老古董了。但是大多还在应用,其固有的稳定性,一直也在有市场份额。但是,随着一个高大上的产品出来之后,51单片机有点力不从心了。stm32,dsp的崛起,给51单片机也快划上了完美的句号。

        我们的本科时候也是学51单片机,老师一直强调他是什么什么基础,如果学单片机一定要从51学起,这句话一点没有错!同样,如果想学好高端的东西,一定要慢慢积累,学习是一个渐变的过程,并不是像动画片里,把书吃进肚子里,之后就什么都会了一样。

        我要感谢我的大学老师,fan老师,他教会了我很多单片机的知识,他也自己出了几本单片机的书以及在淘宝网上卖开发板。很帅气的老师,人长的也相当的精神。接下来就来给大家送出海量资源------stm8的各种应用程序!最重要的是应用!全部都是我自己调试的,编译都通过的程序。硬件电路也很简单,有什么不懂的可以提出来,我们一起去讨论,我也在和你们学习。谢谢大家!

 

全部回复(59)
正序查看
倒序查看
2014-04-08 13:06
第一个:LED闪烁
/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */
#include "stm8s208r.h"
/******************函数声明***************************************/
void delay(unsigned int time);
/******************主函数***************************************/
void main(void)
{
	PB_DDR |= 0x01;							//选择输出模式
	PB_CR1 |= 0x01;							//推挽输出模式
	PB_CR2 |= 0x00;							//低速输出模式
	while (1)
	{
		PB_ODR &= 0xfe;					//小灯亮
		delay(50000);					//调用延时函数
		PB_ODR |= 0x01;					//小灯灭
		delay(50000);					//调用延时函数
	}	
}
/******************延时子程序***************************************/
void delay(unsigned int time)
{
	while(time --);					//在此循环time次,实现延时
}
 
0
回复
2014-04-08 13:08

第二个:STM8控制8个数码管

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
/*---------------------函数声明--------------------------*/
void delay(unsigned int delay_time);
void display_SMG(void);
/*----------------SMG_table 共阳数码管段选编码-----------*/
unsigned char SMG_table[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/*---------------对应显示数字0123456789------------------*/
main()
{	
/*--------------端口初始化-------------------------------*/
	PB_DDR = 0XFF;  					//定义PB口为输出,用于控制数码管段选
	PB_ODR = 0XFF;						//定义PB初始输出为高,数码管初始不亮
	PB_CR1 = 0XFF;						//定义推挽输出	
	PB_CR2 = 0XFF;						//定义快速输出
	PG_DDR = 0XFF;  					//定义PG口为输出,用于控制数码管段选
	PG_ODR = 0XFF;						//定义PG初始输出为高,数码管初始不亮
	PG_CR1 = 0XFF;						//定义推挽输出	
	PG_CR2 = 0XFF;						//定义快速输出
/*-------------------------------------------------------*/	
	while (1)
	{
		display_SMG();					//用数码管显示数字
	}
}
/*--------------数码管显示函数----------------------------*/
void display_SMG(void)
{
	/*--------------第8个数码管显示2------------------------*/
	PB_ODR = SMG_table[2];	 //段选,让全部数码管显示2 
	PG_ODR = 0X7F;					 //位选,0111 1111 让第8个数码管亮
	delay(500);
	/*--------------第7个数码管显示0------------------------*/
	PB_ODR = SMG_table[0];
	PG_ODR = 0XBF;					 //段选,让全部数码管显示0
	delay(500);							 //位选,1011 1111 让第7个数码管亮
	/*--------------第6个数码管显示1------------------------*/
	PB_ODR = SMG_table[1];
	PG_ODR = 0XDF;					 //段选,让全部数码管显示1 
	delay(500);							 //位选,1101 1111 让第6个数码管亮
	/*--------------第5个数码管显示1------------------------*/
	PB_ODR = SMG_table[1];
	PG_ODR = 0XEF;					 //段选,让全部数码管显示1
	delay(500);							 //位选,1110 1111 让第5个数码管亮
	/*--------------第4个数码管显示0------------------------*/
	PB_ODR = SMG_table[0];
	PG_ODR = 0XF7;					 //段选,让全部数码管显示0
	delay(500);							 //位选,1111 0111 让第4个数码管亮
	/*--------------第3个数码管显示1------------------------*/
	PB_ODR = SMG_table[1];
	PG_ODR = 0XFB;					 //段选,让全部数码管显示1
	delay(500);							 //位选,1111 1011 让第3个数码管亮
	/*--------------第2个数码管显示1------------------------*/
	PB_ODR = SMG_table[1];
	PG_ODR = 0XFD;					 //段选,让全部数码管显示1
	delay(500);						 	 //位选,1111 1101 让第2个数码管亮
	/*--------------第1个数码管显示0------------------------*/
	PB_ODR = SMG_table[0];
	PG_ODR = 0XFE;					 //段选,让全部数码管显示0
	delay(500);							 //位选,1111 1110 让第1个数码管亮
}
/*--------------延时函数----------------------------*/
void delay(unsigned int delay_time)
{
	while(delay_time != 0)
	{
		delay_time--;
	}
}

 

0
回复
2014-04-08 13:08
@SKY丶辉煌
第一个:LED闪烁/*MAIN.Cfile**Copyright(c)2002-2005STMicroelectronics*/#include"stm8s208r.h"/******************函数声明***************************************/voiddelay(unsignedinttime);/******************主函数***************************************/voidmain(void){PB_DDR|=0x01;//选择输出模式PB_CR1|=0x01;//推挽输出模式PB_CR2|=0x00;//低速输出模式while(1){PB_ODR&=0xfe;//小灯亮delay(50000);//调用延时函数PB_ODR|=0x01;//小灯灭delay(50000);//调用延时函数}}/******************延时子程序***************************************/voiddelay(unsignedinttime){while(time--);//在此循环time次,实现延时} 
不错 学习学习
0
回复
2014-04-08 13:09

第三个:stm8直接驱动一个数码管

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
/*---------------------函数声明--------------------------*/
void delay(unsigned int delay_time);
void display_SMG(void);
/*----------------SMG_table 共阳数码管段选编码-----------*/
unsigned char SMG_table[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/*---------------对应显示数字0123456789------------------*/
main()
{	
/*--------------端口初始化-------------------------------*/
	PB_DDR = 0XFF;  					//定义PB口为输出,用于控制数码管段选
	PB_ODR = 0XFF;						//定义PB初始输出为高,数码管初始不亮
	PB_CR1 = 0XFF;						//定义推挽输出	
	PB_CR2 = 0XFF;						//定义快速输出
/*-------------------------------------------------------*/	
	while (1)
	{
		display_SMG();					//用一个数码管显示数字
	}
}
/*--------------数码管显示函数----------------------------*/
void display_SMG(void)
{
	unsigned int i;
	/*--------------用一个数码管显示0~9---------------------*/
	for(i = 0;i < 10;i ++)
	{
		PB_ODR = SMG_table[i];
		delay(50000);
	}
}
/*--------------延时函数----------------------------*/
void delay(unsigned int delay_time)
{
	while(delay_time != 0)
	{
		delay_time--;
	}
}

 

0
回复
2014-04-08 13:09

第四个:tim1捕获比较通道数数

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
/*******************函数声明*******************************/
void TIM1_Init(void);
void GPIO_Init(void);
/*******************主函数*********************************/
main()
{
	GPIO_Init();
	TIM1_Init();
	//开启TIM1
	TIM1_CR1 |= 0X01;
	while (1)
	{
		PB_ODR = ~TIM1_CNTRL;
	}
}
/*******************TIM1外部时钟模式1初始化****************/
void TIM1_Init(void)
{
	//输入捕获1滤波器设置为采样频率FSAMPLING = FMASTER/32,N = 8
	TIM1_CCMR1 |= 0XF0;
	//捕获发生在TI2F的低电平或下降沿
	TIM1_CCER1 = 0x20;
	//TIM1工作在外部时钟模式1
	TIM1_SMCR |= 0X07;
	//选择TI2作为输入源
	TIM1_SMCR |= 0X60;
}
/*******************GPIOC初始化****************************/
void GPIO_Init(void)
{
	//PB口显示TIM1_CNTRL中的值,设置PB口为推挽快速输出方式
	PB_ODR = 0XFF;
	PB_DDR = 0XFF;
	PB_CR1 = 0XFF;
	PB_CR2 = 0XFF;
	//PC2为TIM1的捕获/比较通道2,设置为上拉输入
	PC_DDR = 0X00;
	PC_CR1 = 0XFF;
}

 

0
回复
2014-04-08 13:10

第5个:TIM1定时产生1HZ方波信号

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
/*********************函数声明****************************/
void GPIO_Init(void);
void TIM1_Init(void);
void delay(unsigned int time);
void main(void)
{
	GPIO_Init();
	TIM1_Init();
	TIM1_CR1 |= 0X01;						//置位CEN位,开始计数
	_asm("rim");
	while (1);
}
/*********************GPIO初始化***************************/
void GPIO_Init(void)
{
	PB_ODR |= 0X01;							//PB0上电为1
	PB_DDR |= 0X01;							//设置PB0口为输出
	PB_CR1 |= 0X01;							//推挽输出
	PB_CR2 |= 0X01;							//快速输出
}
/*********************TIM1初始化***************************/
void TIM1_Init(void)
{
	//系统时钟为2Mhz,20分频,计数器频率为100Khz
	TIM1_PSCRH = 0;
	TIM1_PSCRL = 19;
	//开溢出中断
	TIM1_IER = 0X01;
	//计数50000次,为0.5s
	TIM1_ARRH = (unsigned char)(50000 >> 8);
	TIM1_ARRL = (unsigned char)50000;
	//设置计数器的值,使定时器一开始即可产生更新事件
	TIM1_CNTRH = (unsigned char)(50000 >> 8);
	TIM1_CNTRL = (unsigned char)50000;
}
/*********************延时函数*****************************/
void delay(unsigned int time)
{
	while(time --);
}
/*****************TIM1溢出中断服务程序*********************/
@far @interrupt void TIM1_OVF_IRQ(void)
{
	TIM1_SR1 &= 0XFE;
	PB_ODR ^= 0X01;
}

 

0
回复
2014-04-08 13:11

第6个:定时500ms让LED闪起来

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
unsigned int count = 0;
/*****************函数声明************************/
void GPIO_Init(void);
void TIM4_Init(void);
/*****************主函数**************************/
main()
{
	GPIO_Init();
	TIM4_Init();
	_asm("rim");
	TIM4_CR1 |= 0X01;				//开始计时
	while (1);
}
/*****************GPIO初始化**********************/
void GPIO_Init(void)
{
	PB_ODR = 0X00;					//输出初始值为0X00;
	PB_DDR = 0XFF;					//设置PB口方向为输出
	PB_CR1 = 0XFF;					//设置为推挽输出
	PB_CR2 = 0X00;					//低速模式
}
/*****************TIM4初始化**********************/
void TIM4_Init(void)
{
	TIM4_PSCR = 0X03;				//预分频值2MHZ/(2^3) = 250khz
	TIM4_IER = 0X01;				//开定时器中断
	TIM4_ARR = 250;					//自动重装值,1/250k*250 = 1ms
	TIM4_CNTR = 250;				//计数器初始值给250,目的是一开始
													//级计数就产生一次溢出从而产生更新
													//事件来使预分频器的值启用
}
/*****************TIM4中断服务程序**********************/
@far @interrupt void TIM4_IRQ(void)
{
	count ++;
	TIM4_SR = 0X00;
	if(count == 500)
	{
		PB_ODR ^= 0XFF;
		count = 0;
	}
}

 

0
回复
2014-04-08 13:12

第7个:独立按键启用内部上拉

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
/*---------------------函数声明--------------------------*/
void delay(unsigned int delay_time);
void display_SMG(void);
void key_press(void);
/*----------------SMG_table 共阳数码管段选编码-----------*/
unsigned char SMG_table[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/*---------------对应显示数字0123456789------------------*/
/*-------------------------------------------------------*/
unsigned char Number;				//显示的数字
main()
{	
/*--------------端口初始化-------------------------------*/
	PB_DDR = 0XFF;  					//定义PB口为输出,用于控制数码管段选
	PB_ODR = 0XFF;						//定义PB初始输出为高,数码管初始不亮
	PB_CR1 = 0XFF;						//定义推挽输出	
	PB_CR2 = 0XFF;						//定义快速输出
	PE_DDR &= 0XFE;						//定义PE0口为输入,检测按键输入
	PE_CR1 |= 0X01;						//定义为上拉输入,芯片内部启用上拉电阻
	PE_CR2 &= 0XFE;						//定义不时能中断
/*-------------------------------------------------------*/	
	while (1)
	{
		key_press();						//用查询法判断按键是否按下
		display_SMG();					//用数码管显示Number值
	}
}
/*----------------按键处理函数----------------------------*/
void key_press()
{
/*----------------判断按键是否按下------------------------*/
	if((PE_IDR & 0X01) == 0)
	{
		delay(13000);						//延时10~20ms去除抖动
		if((PE_IDR & 0X01) == 0)//再次判断按键是否按下,若按下,Number+1
		{
			if(Number < 9)
				Number++;
			else
				Number = 0;
		}
	}
}
/*--------------数码管显示函数----------------------------*/
void display_SMG(void)
{
/*----------------用一个数码管显示Number------------------*/
	PB_ODR = SMG_table[Number];
}
/*--------------延时函数----------------------------*/
void delay(unsigned int delay_time)
{
	while(delay_time != 0)
	{
		delay_time--;
	}
}

 

0
回复
SKY丶辉煌
LV.10
10
2014-04-08 13:13

第8个:跑马灯

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */
#include"stm8s208r.h"			//开始时的头文件包含
/***********************函数声明***************************/
void delay(unsigned int time);					//声明延时函数
/***********************主函数*****************************/
void main(void)
{
	unsigned char i = 0;
	PB_ODR = 0XFF;          //设置输出寄存器的输出数值,初始
													//化小灯全灭
	PB_DDR = 0XFF;					//设置I/O口B为输出
	PB_CR1 = 0XFF;					//设置I/O口B为推挽方式
	PB_CR2 = 0X00;					//输出最快速度为2MHZ
	while (1)
	{
			switch(i)						//让小灯从低位到高位依次亮
			{
					case 0:	PB_ODR = 0XFE;
									break;
					case 1:	PB_ODR = 0XFD;
									break;
					case 2:	PB_ODR = 0XFB;
									break;
					case 3:	PB_ODR = 0XF7;
									break;
					case 4:	PB_ODR = 0XEF;
									break;
					case 5:	PB_ODR = 0XDF;
									break;	
					case 6:	PB_ODR = 0XBF;
									break;	
					case 7:	PB_ODR = 0X7F;
									break;
					default :PB_ODR = 0XFE;
			}
			delay(40000);			  //延时约20ms
			i++;								//让i加1下次执行程序时进入到case
			if(i == 8)
			{
					i = 0;
			}
	}
}
/*******************延时子程序***************************/
void delay(unsigned int time)
{
	while(time --);						//让while执行time次程序达到延时 的目的
}

 

0
回复
SKY丶辉煌
LV.10
11
2014-04-08 13:14

第9个:数组与万能流水灯

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */
#include"stm8s208r.h"
/********************定义一个二维数组*********************/
/********************装入使小灯花样闪亮的数据*************/
/*********************************************************/
unsigned char dis[5][8] =
{
{0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f},
{0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe},
{0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff},
{0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00},
{0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f}
};
/************************函数声明**************************/
void GPIO_Init(void);										//GPIO口的初始化子程序
void display(void);											//用PB口显示花样小灯子程序
void delay(unsigned int time);					//延时子程序
/************************主函数****************************/
int main(void)
{
	GPIO_Init();													//端口初始化
	while (1)															//死循环
	{
		display();													//始终让小灯显示花样
	}
}
/************************GPIO口的初始化****************************/
void GPIO_Init(void)
{
	PB_ODR = 0XFF;												//初始使小灯全灭
	PB_DDR = 0XFF;												//DDR为0是输入,1是 输出。 此处为PB的8个端口均为输出
	PB_CR1 = 0XFF;												//推挽输出模式
	PB_CR2 = 0X00;												//低速输出模式
}
/************************小灯花样显示子程序************************/
void display(void)
{
	unsigned char i,j;
	for(i =0;i<5;i++)											//循环二维数组的行数
	{
		for(j= 0;j<8;j++)										//循环二维数组的每行中的数据
		{
			PB_ODR = dis[i][j];								//把数据给PB口使小灯显示
			delay(50000);
		}
	}
}
/*****************************延时子程序*****************************/
void delay(unsigned int time)
{
	while(time--);
}

 

0
回复
SKY丶辉煌
LV.10
12
2014-04-08 13:15

第10个:外部按键中断

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"						//必须包含的头文件
/******************函数声明****************************/
void delay(unsigned int time);
/********************主函数****************************/
main()
{
	EXTI_CR1 = 0XF2;							//设置端口A的中断出发方式为 仅下降沿触发
	PA_DDR &= 0XEF;								//设置PA4脚为输入模式,当做 中断触发引脚连接按键
	PB_DDR = 0XFF;								//设置端口B的所有引脚均为输 出,控制小灯
	PA_CR1 |= 0X10;								//设置PA4为中断上拉输入方式
	PA_CR2 |= 0X10;
	PB_CR1 |= 0XFF;								//设置端口B为推挽输出模式
	PB_CR2 &= 0X00;
	_asm("rim");									//这是一条汇编语句,功能是打开总的中断使能
	PB_ODR = 0X0F;								//让小灯的高4位亮
	while(1);											//因为用中断程序控制小灯所以死循环内空跑
}
/*******************中断服务程序***********************/
@far @interrupt void EXTI_PORTA_IRQHandler(void)
{
	if((PA_IDR & 0X10) == 0)					//判断是否是PA4出发产生 的中断
	{
		delay(50);											//延时去抖
		if((PA_IDR &0X10) == 0)					//判断是否依然是低,若是则说明不是抖动
		{
			while((PA_IDR & 0X10) == 0);	//等待松开
			PB_ODR = ~PB_ODR;							//取反让小灯高低4位交替 亮灭
		}
	}
}
/*******************延时子程序**************************/
void delay(unsigned int time)
{
	while(time --);
}

 

0
回复
SKY丶辉煌
LV.10
13
2014-04-08 13:15

第11个:心律不齐的LED分频因子

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
_Bool LED @PG_ODR:0;
void Delay(unsigned int t);
main()
{
	unsigned char i;
	PG_DDR |= 0X01;
	PG_CR1 |= 0X01;
	PG_CR2 |= 0X01;
	while(1)
	{
		//HSI不分频,单片机工作在16MHZ
		CLK_CKDIVR = 0X00;
		for(i = 0;i<5;i++)
		{
			LED = 0;
			Delay(50000);
			LED = 1;
			Delay(50000);
		}
		//HSI 8分频,单片机工作在2MHZ
		CLK_CKDIVR = 0X18;
		for(i = 0;i<5;i++)
		{
			LED = 0;
			Delay(50000);
			LED = 1;
			Delay(50000);
		}

	}
}
void Delay(unsigned int t)
{
	while(t--);
}

 

0
回复
SKY丶辉煌
LV.10
14
2014-04-08 13:16

第12个:用for循环遛马

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"									//包含stm8头文件
/***********************函数声明**********************/
void delay(unsigned int time);				//延时函数

/************************主函数***********************/
void main(void)
{
	unsigned char i;
	PB_ODR = 0XFE;											//低电平有效,点亮第一个LED
	PB_ODR = 0XFF;											//I/O口初始化,将PB口 设为输出状态
	PB_CR1 = 0XFF;											//PB口(CR1)置1推挽输出
	PB_CR2 = 0X00;											//CR2置0低速模式,初始化完成
	while (1)
	{
		PB_ODR = 0XFE;
		for(i = 0;i <8;i++)								//赋初值配合for循环使 用
		{
			delay(50000);
			PB_ODR <<= 1;										//左移一位,点亮下一个LED
			PB_ODR |= 0X01;									//左移后最低位自动补0 ,所以需要将最低位置高
		}
	}
}
/********************延时子程序***********************/
void delay (unsigned int time)
{
	while(time --);
}

 

0
回复
SKY丶辉煌
LV.10
15
2014-04-08 13:17

第13个:中断嵌套,中断优先级

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
void delay(unsigned int t);
main()
{
	//8个LED
	PG_ODR = 0XFF;
	PG_DDR = 0XFF;
	PG_CR1 = 0XFF;
	PG_CR2 = 0X00;
	
	//PD6中断
	PD_DDR &= ~(1 << 7);
	PD_CR1 |= (1 << 7);
	//仅下降沿触发
	EXTI_CR2 |= 0X04;
	PD_CR2 |= (1 << 7);
	
	//PD7中断
	PD_DDR &= ~(1 << 6);
	PD_CR1 |= (1 << 6);
	//仅下降沿触发
	EXTI_CR1 |= (2 << 6);
	PD_CR2 |= (1 << 6);
	
	//PB软件优先级设置为1级
	ITC_SPR2 &= ~(1 << 1);
	
	//PB6中断
	PB_DDR &= ~(1 << 6);
	PB_CR1 |= (1 <<6);
	//仅下降沿触发
	EXTI_CR1 |= (2 << 2);
	PB_CR2 |= (1 << 6);
	
	//开总中断
	_asm("rim");
	while (1)
	{
		PG_ODR = 0X00;
	}
}
void delay(unsigned int t)
{
	unsigned int i;
	while(t--)
	for(i = 0;i< 5000; i++);
}
@far @interrupt void PB_IRQ(void)
{
	if((PB_IDR & (1 << 6)) == 0)
	{
		PG_ODR = 0X0F;
		delay(50);
		PG_ODR = 0X0F;
		delay(50);
		_asm("sim");
	}
}
@far @interrupt void PD_IRQ(void)
{
	if((PD_IDR & (1 << 6)) == 0)
	{
		PG_ODR = 0XF0;
		delay(50);
		PG_ODR = 0XF0;
		delay(50);
	}
}
@far @interrupt void TLI_IRQ(void)
{
	PG_ODR = 0XAA;
	delay(10);
}

 

 

0
回复
SKY丶辉煌
LV.10
16
2014-04-08 13:18
@SKY丶辉煌
第13个:中断嵌套,中断优先级/*MAIN.Cfile**Copyright(c)2002-2005STMicroelectronics*/#include"stm8s208r.h"voiddelay(unsignedintt);main(){//8个LEDPG_ODR=0XFF;PG_DDR=0XFF;PG_CR1=0XFF;PG_CR2=0X00;//PD6中断PD_DDR&=~(1
下午要去上课,毛泽东思想和邓小平理论,晚上回来再更新。高档单片机或者dsp最强大的是其库功能!
0
回复
SKY丶辉煌
LV.10
17
2014-04-08 13:19
@SKY丶辉煌
下午要去上课,毛泽东思想和邓小平理论,晚上回来再更新。高档单片机或者dsp最强大的是其库功能!

有关中断的程序,interrupt里面的程序未给出,晚上回来也会补充。

谢谢大家,跟大家学习。

0
回复
2014-04-08 13:24
@SKY丶辉煌
有关中断的程序,interrupt里面的程序未给出,晚上回来也会补充。谢谢大家,跟大家学习。
  好棒~
0
回复
SKY丶辉煌
LV.10
19
2014-04-08 19:25
@电源网-俪俪
[图片] 好棒~
谢谢
0
回复
SKY丶辉煌
LV.10
20
2014-04-08 22:27

第14个:tim1外部时钟源模式2从外部触发引脚数脉冲数

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */
#include"stm8s208r.h"
/********************函数声明****************************/
void TIM1_Init(void);
void GPIO_Init(void);
/********************主函数******************************/

main()
{
	GPIO_Init();
	TIM1_Init();
	//开启TIM1
	TIM1_CR1 |= 0X01;
	while (1)
	{
		PE_ODR = ~TIM1_CNTRL;
	}
}
/******************TIM1外部时钟模式1初始化*****************/
void TIM1_Init(void)
{
	//低电平或下降沿有效
	TIM1_ETR |= 0X80;
	//外部触发预分频值为2
	TIM1_ETR |= 0X10;
	//外部触发滤波器设置为采样频率Fsampling = Fmaster/32,N=8
	TIM1_ETR |= 0X0F;
	//使能外部时钟模式2
	TIM1_ETR |= 0X40;
}
/****************GPIO初始化********************************/
void GPIO_Init(void)
{
	//PG口显示TIM1_CNTRL中的值
	PG_ODR = 0XFF;
	PG_DDR = 0XFF;
	PG_CR1 = 0XFF;
	PG_CR2 = 0XFF;
	//PB3为TIM1外部触发引脚,设置为上拉输入
	PB_DDR = 0X00;
	PB_CR1 = 0XFF;
}

 

0
回复
SKY丶辉煌
LV.10
21
2014-04-08 22:27

第15个:tim1测量方波周期

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
unsigned long frequency;
unsigned int captureValue1,captureValue2;
unsigned char gewei,shiwei,baiwei,qianwei;
unsigned char dis[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void TIM1_Init(void);
void CCO_Init(void);
void GPIO_Init(void);
void Display(void);
void Delay(unsigned int t);
main()
{
	unsigned int i;
	/********************系统时钟不分频,为16Mhz*************/
	CLK_CKDIVR = 0X00;
	GPIO_Init();
	CCO_Init();
	TIM1_Init();
	while (1)
	{
		/********************捕获使能**************************/
		TIM1_CCER1 |= 0X01;
		/*******************等待CC1IF被置位********************/
		while((TIM1_SR1 & 0X02) == 0);
		captureValue1 = (unsigned int)TIM1_CCR1H << 8;
		captureValue1 |= TIM1_CCR1L;
		/*******************等待第二次被置位******************/
		while((TIM1_SR1 & 0X02) == 0);
		captureValue2 = (unsigned int)TIM1_CCR1H << 8;
		captureValue2 |= TIM1_CCR1L;
		/*******************捕获禁止**************************/
		TIM1_CCER1 &= 0XFE;
		/*(captureValue2 - captureValue1)/16000000为测量周期,
					因为进行了8分频,所以实际频率*8  ***************/
		frequency = (8 * 16000000UL)/(captureValue2 - captureValue1);
		/*****************单位换算成khz,小数点后1位**********/
		frequency = frequency/100;
		/*****************显示频率****************************/
		for(i = 0;i < 500;i++)
		Display();
	}
}
void CCO_Init(void)
{
	/*****************时钟输出为FLSI******************/
	CLK_CCOR |= 0X02;
	/****************开启CCO时钟输出******************/
	CLK_CCOR |= 0X01;
}
void TIM1_Init(void)
{
	//CC1通道被配置为输入,IC1映射在TI1FP1上
	TIM1_CCMR1 |= 0X01;
	//IC1PSC[1:0]被配置为11,即8分频
	TIM1_CCMR1 |= (0X03 << 2);
	//定时器开始计数
	TIM1_CR1 |= 0x01;
}
void GPIO_Init(void)
{
	//数码管段选
	PG_ODR = 0XFF;
	PG_DDR = 0XFF;
	PG_CR1 = 0XFF;
	PG_CR2 = 0XFF;
	//数码管位选
	PB_ODR = 0XFF;
	PB_DDR = 0XFF;
	PB_CR1 = 0XFF;
	PB_CR2 = 0XFF;
}
void Display(void)
{
	qianwei = frequency / 1000;
	baiwei = (frequency % 1000) / 100;
	shiwei = (frequency % 100) / 10;
	gewei = frequency % 10;
	PG_ODR = dis[gewei];
	PB_ODR = 0XFE;
	Delay(100);
	PB_ODR = 0XFF;
	//十位亮小数点
	PG_ODR = dis[shiwei] & 0x7f;
	PB_ODR = 0XFD;
	Delay(100);
	PB_ODR = 0XFF;
	PG_ODR = dis[baiwei];
	PB_ODR = 0XFB;
	Delay(100);
	PB_ODR = 0XFF;
	PG_ODR = dis[gewei];
	PB_ODR = 0XF7;
	Delay(100);
	PB_ODR = 0XFF;
}
void Delay(unsigned int t)
{
	while(t --);
}

 

0
回复
SKY丶辉煌
LV.10
22
2014-04-08 22:28

第十六个:tim1测量pwm方波占空比

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
unsigned long frequency;
unsigned char dutyCycle;
unsigned int captureValue1,captureValue2;
unsigned char gewei,shiwei,baiwei,qianwei,dutyCycle1,dutyCycle2;
unsigned char dis[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void TIM1_Init(void);
void GPIO_Init(void);
void Display(void);
void Delay(unsigned int t);
main()
{
	unsigned int i;
	//系统时钟不分频,为16Mhz
	CLK_CKDIVR = 0X00;
	GPIO_Init();
	TIM1_Init();
	while (1)
	{
		//清除CC1IF,CC2IF标志位
		TIM1_SR1 &= 0XF9;
		//清除CC1OF标志位
		TIM1_SR2 &= 0XFD;
		//使能捕获,CC1E = 1,CC2E = 1
		TIM1_CCER1 |= 0X11;
		while((TIM1_SR1 & 0X02) == 0);
		//等待CC2IF被置位
		while((TIM1_SR1 & 0X04) == 0);
		captureValue1 = (unsigned int)TIM1_CCR2H << 8;
		captureValue1 |= TIM1_CCR2L;
		//等待CC1OF被置位
		while((TIM1_SR2 & 0X02) == 0);
		captureValue2 = (unsigned int)TIM1_CCR1H << 8;
		captureValue2 |= TIM1_CCR1L;
		//捕获禁止
		TIM1_CCER1 &= 0XEE;
		//16000000UL/captureValue2为测量周期,取倒数为频率
		frequency = (16000000UL/captureValue2);
		//单位换算成KHZ,小数点后1位
		frequency = frequency / 100;
		//captureValue1/captureValure2为占空比
		dutyCycle = (captureValue1 * 100)/captureValue2;
		//显示频率
		for(i = 0; i < 400; i++)
		Display();
	}
}
void TIM1_Init(void)
{
	//CC1通道被配置为输入,IC1映射在TI1FP1上,CC1S = 01
	TIM1_CCMR1 |= 0X01;
	//TI1FP1上升沿有效,CC1P = 0
	TIM1_CCER1 &= ~(1 << 1);
	//CC2通道被配置为输入,IC2映射在TI1FP2上CC2S = 10
	TIM1_CCMR2 |= 0X02;
	//TI1FP2下降沿有效,CC2P = 1
	TIM1_CCER1 |= (1 << 5);
	//触发输入信号为TI1FP1,TS = 101
	TIM1_SMCR |= 0X50;
	//触发模式为复位触发,SMS = 100
	TIM1_SMCR |= 0X04;
	//定时器开始计数
	TIM1_CR1 |= 0X01;
}
void GPIO_Init(void)
{
	//数码管段选
	PG_ODR = 0XFF;
	PG_DDR = 0XFF;
	PG_CR1 = 0XFF;
	PG_CR2 = 0XFF;
	//数码管位选
	PB_ODR = 0XFF;
	PB_DDR = 0XFF;
	PB_CR1 = 0XFF;
	PB_CR2 = 0XFF;
}
void Display(void)
{
	qianwei = frequency / 1000;
	baiwei = (frequency % 1000) / 100;
	shiwei = (frequency % 100) / 10;
	gewei = frequency % 10;
	dutyCycle1 = dutyCycle % 10;
	dutyCycle2 = dutyCycle / 10;
	
	PG_ODR = dis[gewei];
	PB_ODR = 0XFE;
	Delay(100);
	PB_ODR = 0XFF;
	//十位亮小数点
	PG_ODR = dis[shiwei] & 0x7f;
	PB_ODR = 0XFD;
	Delay(100);
	PB_ODR = 0XFF;
	
	PG_ODR = dis[baiwei];
	PB_ODR = 0XFB;
	Delay(100);
	PB_ODR = 0XFF;
	
	PG_ODR = dis[qianwei];
	PB_ODR = 0XF7;
	Delay(100);
	PB_ODR = 0XFF;
	
	PG_ODR = dis[dutyCycle2];
	PB_ODR = 0X7F;
	Delay(100);
	PB_ODR = 0XFF;
	
	PG_ODR = dis[dutyCycle1];
	PB_ODR = 0XBF;
	Delay(100);
	PB_ODR = 0XFF;
}
void Delay(unsigned int t)
{
	while(t --);
}

 

0
回复
SKY丶辉煌
LV.10
23
2014-04-08 22:29

第17个:tim1边沿对齐pwm

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */
/*******************************************************
**  		功能:PWM控制直流电机转速
**	 		描述:TIM1工作在边沿对齐模式 (向上计数)
**							PC1输出 75%占空比的PWM
**							PC2输出	50%占空比的PWM
**			说明:使用内部HSI 16MHZ
*******************************************************/

#include"stm8s208r.h"
_Bool IN1 @PB_ODR:3;
_Bool IN2 @PB_ODR:4;
_Bool IN3 @PB_ODR:5;
_Bool IN4 @PB_ODR:6;

void GPIO_Init(void);
void MotorCW(void);
void MotorCCW(void);
void MotorStop(void);
void TIM1_OC1_INIT(void);
void TIM1_OC2_INIT(void);
void Delay(unsigned int t);

main()
{
	//内部HSI时钟不分频,f= 16MHZ
	CLK_CKDIVR = 0X00;
	GPIO_Init();
	TIM1_OC1_INIT();
	TIM1_OC2_INIT();
	while (1)
	{
		MotorCW();
		Delay(60000);
		MotorCCW();
		Delay(60000);
		MotorStop();
		Delay(60000);
	}
}
void Delay(unsigned int t)
{
	while(t--);
}
void GPIO_Init(void)
{
	PB_DDR = 0X78;
	PB_CR1 = 0X78;
	PB_CR2 = 0X78;
}
void MotorCW(void)
{
	IN1 = 1;
	IN2 = 0;
	IN3 = 1;
	IN4 = 0;
}
void MotorCCW(void)
{
	IN1 = 0;
	IN2 = 1;
	IN3 = 0;
	IN4 = 1;
}
void MotorStop(void)
{
	IN1 = 0;
	IN2 = 0;
	IN3 = 0;
	IN4 = 0;
}
void TIM1_OC1_INIT(void)
{
	//定时器溢出值TIM1_ARR = 0X3E80 = 16000,输出波形频率为1KHZ
	TIM1_ARRH = 0X3E;
	TIM1_ARRL = 0X80;
	//CCR1 = 0X2EE0 = 12000,输出波形占空比为75%
	TIM1_CCR1H = 0X2E;
	TIM1_CCR1L = 0XE0;
	//OC1M[110]PWM1模式
	TIM1_CCMR1 = 0X60;
	//CC1P = 0,CC1E = 1;高电平有效
	TIM1_CCER1 = 0X01;
	//空闲状态为高
	TIM1_OISR = 0X01;
}
void TIM1_OC2_INIT(void)
{
	//CCR2 = 0X1F40 = 8000,输出波形占空比为50%
	TIM1_CCR2H = 0X1F;
	TIM1_CCR2L = 0X40;
	//0C2M[110]PWM1模式
	TIM1_CCMR2 = 0X60;
	//CC2P = 0,CC2E = 1;高电平有效
	TIM1_CCER2 = 0X11;
	//空闲状态为高
	TIM1_OISR = 0X01;
	//CEN = 1开定时器,CMS[1:0]边沿对齐模式DIR选择向上计数模式
	TIM1_CR1 = 0X01;
	//打开OCI输出使能
	TIM1_BKR = 0X80;
}

 

0
回复
SKY丶辉煌
LV.10
24
2014-04-09 08:45

第18个:AD简易数字电压表

/* MAIN.C file
 * 
 * Copyright (c) 2002-2005 STMicroelectronics
 */

#include"stm8s208r.h"
unsigned char const shumaguan[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//ADCValue数组存放A/D采样值,voltageADC为数字滤波后的结果
unsigned int ADCValue[10] = {0},voltageADC = 0;
//voltage为电压计算结果,单位mV
unsigned int voltage = 0;

void GPIO_Init(void);
void ADC_Init(void);
void ADConvert(void);
void DigitalFiltering(void);
void Display(void);
void Delay(unsigned int t);
main()
{
	unsigned char i;
	GPIO_Init();
	ADC_Init();
	while (1)
	{
		//连续转换10次
		ADConvert();
		//数字滤波
		DigitalFiltering();
		i = 200;
		while(i--)
		Display();
	}
}
void GPIO_Init(void)
{
	//PG口数码管段选,PE口数码管位选
	PG_ODR = 0XFF;
	PG_DDR = 0XFF;
	PG_CR1 = 0XFF;
	PE_ODR = 0XFF;
	PE_DDR = 0XFF;
	PE_CR1 = 0XFF;
}
void ADC_Init(void)
{
	//fADC = fMaster/2,连续转换模式
	ADC_CR1 = 0x02;
	//选择通道0(PB0)?
	ADC_CSR = 0X00;
	//数据右对齐
	ADC_CR2 |= 0X08;
	//从低功耗模式唤醒
	ADC_CR1 |= 0X01;
}
void ADConvert(void)
{
	unsigned char count = 0;
	//开启连续转换,不可直接写入0X03
	ADC_CR1 |= 0X02;
	ADC_CR1 |= 0X01;
	ADC_CR1 |= 0x01;
	while(count < 10)
	{
		//等待转换结束
		while((ADC_CSR & 0X80) == 0);
		//清除转换结束标志位
		ADC_CSR &= ~0X80;
		ADCValue[count] = (unsigned int)ADC_DRL;
		ADCValue[count] |= (unsigned int)ADC_DRH << 8;
		count++;
	}
	//关闭连续转换
	ADC_CR1 &= ~0X02;
}
void DigitalFiltering(void)
{
	unsigned char i,j;
	unsigned int temp;
	//对数组排序
	for(i = 10;i >= 1;i--)
	{
		for(j = 0;j <(i-1);j++)
		{
			if(ADCValue[j] > ADCValue[j +1])
			{
				temp = ADCValue[j];
				ADCValue[j] = ADCValue[j +1];
				ADCValue[j +1] = temp;
			}
		}
	}
	//舍弃最大和最小的两个数,然后求平均值
	voltageADC = 0;
	for(i = 2;i <= 7;i++)
	voltageADC += ADCValue[i];
	voltageADC/6;
}
void Display(void)
{
	unsigned char displayArray[4],i;
	//voltage/3300(mV)= voltageADC/1023
	voltage = (unsigned int)((unsigned long)voltageADC * 3240UL / 1023UL);
	//拆分数据,使用数码管显示
	displayArray[3] = voltage / 1000;
	displayArray[2] = (voltage % 1000) / 100;
	displayArray[1] = (voltage % 100) / 10;
	displayArray[0] = voltage % 10;
	//使用数码管显示电压值,单位mV
	for(i = 0;i < 4;i++)
	{
		PG_ODR = shumaguan[displayArray[i]];
		PE_ODR = ~(0X01 << i);
		Delay(100);
		PE_ODR = 0xff;
	}
}
void Delay(unsigned int t)
{
	while(t--);
}

 

0
回复
SKY丶辉煌
LV.10
25
2014-04-10 20:54
看来这款单片机大家了解的甚少啊~
0
回复
秋柳
LV.2
26
2014-04-10 22:17
@SKY丶辉煌
看来这款单片机大家了解的甚少啊~

我觉得其实不是了解甚少,使用的大有人在。

问题在于:1、这单片机比起51系列来,算是新的,高档点的。这电源网里大部分人都是搞电源的,真正研究mcu的还不是很多。

2、你的这些程序,大部分都是个别功能单独实现,并不能做成个项目似的。往往开发板会附带很多这样的程序,没必要仔细去读你的程序。

3、这样的mcu,或者说STM32,大部分人去使用库函数来编程,容易调用,容易读懂,容易嵌入。

所以你这里得到的回答和认可比较少。其实你可以拿些在编程中遇到的问题,跟大家讨论下,会更有价值,共同进步!

0
回复
SKY丶辉煌
LV.10
27
2014-04-11 09:18
@秋柳
我觉得其实不是了解甚少,使用的大有人在。问题在于:1、这单片机比起51系列来,算是新的,高档点的。这电源网里大部分人都是搞电源的,真正研究mcu的还不是很多。2、你的这些程序,大部分都是个别功能单独实现,并不能做成个项目似的。往往开发板会附带很多这样的程序,没必要仔细去读你的程序。3、这样的mcu,或者说STM32,大部分人去使用库函数来编程,容易调用,容易读懂,容易嵌入。所以你这里得到的回答和认可比较少。其实你可以拿些在编程中遇到的问题,跟大家讨论下,会更有价值,共同进步!
谢谢。说的很对。看来我应该把库函数的源文件上传。此贴从此终结,不再更新
0
回复
SKY丶辉煌
LV.10
28
2014-04-11 09:22
SKY丶辉煌
LV.10
29
2014-04-11 09:22
@SKY丶辉煌
AD简易数字电压表(库).rar
0
回复
SKY丶辉煌
LV.10
30
2014-04-11 09:22
@SKY丶辉煌
TIM1边沿对齐PWM(库).rar
0
回复
SKY丶辉煌
LV.10
31
2014-04-11 09:22
@SKY丶辉煌
TIM1捕获比较通道数数(库).rar
0
回复