stm8C语言例程.docx
《stm8C语言例程.docx》由会员分享,可在线阅读,更多相关《stm8C语言例程.docx(42页珍藏版)》请在冰豆网上搜索。
stm8C语言例程
(1);名称:
流水灯
;描述:
;先从上至下点亮所有的LED,再逐个点亮单个LED
;***********************************************************/
#include"stm8s105s4.h"
#defineucharunsignedchar
#defineuintunsignedint
uchartable[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//存放点亮单个LED的代码
voidDelayMS(uints)//延时子函数,约延时1ms
{
uinti;
for(s;s>0;s--)
for(i=0;i<500;i++);
}
voidinit(void)//stm8初始化函数
{
PB_DDR=0xff;
PB_CR1=0xff;//将PB设置成推挽输出
PB_CR2=0x00;
CLK_SWR=0xE1;//选内部高速时钟作为主时钟
CLK_CKDIVR=0x08;//将CPU主频设置为2M(STM8默认的就是内部高速时钟的八分频,即2MH,这里只是告诉大家设置方法)
}
voidmain()
{
uchari;
init();
while
(1)//无限循环
{
PB_ODR=0xff;//先将所有的LED关闭
for(i=0;i<9;i++)//一开始是所有的LED熄灭,再逐点亮所有LED,共九种状态
{
DelayMS(500);//延时500毫秒
PB_ODR<<=1;//将PB_ODR向左移动一位,逐渐点亮所有LED
}
for(i=0;i<8;i++)
{
PB_ODR=table[i];//将table中的数依次赋给PB_ODR,从上至下依次点亮LED
DelayMS(500);
}
}
}
中断向量:
/*BASICINTERRUPTVECTORTABLEFORSTM8devices
*Copyright(c)2007STMicroelectronics
*/
typedefvoid@far(*interrupt_handler_t)(void);
structinterrupt_vector{
unsignedcharinterrupt_instruction;
interrupt_handler_tinterrupt_handler;
};
@far@interruptvoidNonHandledInterrupt(void)
{
/*inordertodetectunexpectedeventsduringdevelopment,
itisrecommendedtosetabreakpointonthefollowinginstruction
*/
return;
}
externvoid_stext();/*startuproutine*/
structinterrupt_vectorconst_vectab[]={
{0x82,(interrupt_handler_t)_stext},/*reset*/
{0x82,NonHandledInterrupt},/*trap*/
{0x82,NonHandledInterrupt},/*irq0*/
{0x82,NonHandledInterrupt},/*irq1*/
{0x82,NonHandledInterrupt},/*irq2*/
{0x82,NonHandledInterrupt},/*irq3*/
{0x82,NonHandledInterrupt},/*irq4*/
{0x82,NonHandledInterrupt},/*irq5*/
{0x82,NonHandledInterrupt},/*irq6*/
{0x82,NonHandledInterrupt},/*irq7*/
{0x82,NonHandledInterrupt},/*irq8*/
{0x82,NonHandledInterrupt},/*irq9*/
{0x82,NonHandledInterrupt},/*irq10*/
{0x82,NonHandledInterrupt},/*irq11*/
{0x82,NonHandledInterrupt},/*irq12*/
{0x82,NonHandledInterrupt},/*irq13*/
{0x82,NonHandledInterrupt},/*irq14*/
{0x82,NonHandledInterrupt},/*irq15*/
{0x82,NonHandledInterrupt},/*irq16*/
{0x82,NonHandledInterrupt},/*irq17*/
{0x82,NonHandledInterrupt},/*irq18*/
{0x82,NonHandledInterrupt},/*irq19*/
{0x82,NonHandledInterrupt},/*irq20*/
{0x82,NonHandledInterrupt},/*irq21*/
{0x82,NonHandledInterrupt},/*irq22*/
{0x82,NonHandledInterrupt},/*irq23*/
{0x82,NonHandledInterrupt},/*irq24*/
{0x82,NonHandledInterrupt},/*irq25*/
{0x82,NonHandledInterrupt},/*irq26*/
{0x82,NonHandledInterrupt},/*irq27*/
{0x82,NonHandledInterrupt},/*irq28*/
{0x82,NonHandledInterrupt},/*irq29*/
};
(2):
矩阵键盘、数码管:
;描述:
按下相应按键显示0到F中对应的数
;***********************************************************/
#include
#defineuintunsignedint
#defineucharunsignedchar
uchartable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
ucharnum;
voiddelay(uchara)
{
uchari;
for(a;a>0;a--)
for(i=0;i<255;i++);
}
voidinit(void)
{
PB_DDR=0XFF;
PB_CR1=0XFF;//将PB设置成推挽输出
PC_DDR=0X1F;
PC_CR1=0XFF;//将PC设置成推挽输出
PE_DDR=0x26;
PE_CR1=0XFF;//将PE5,PE2,PE1为推挽输出,其他的设为上拉输入
PD_DDR=0X80;
PD_CR1=0X80;//将PD7设为推挽输出
}
/***这里的设置比LED的和数码管的设置要复杂,开始引入输入模式,矩阵键盘列为输出,行为输入,请参考协会开发板原理图及STM8转51PDF资料***/
/***扫描方式也可为行输出,列输入,读者可以自己尝试着修改***/
ucharkeys(void)//此子函数看起来很长,实则只有前面一截内容,下面的“同理可得”
{
uchartemp;
PE_ODR=0X26;//将列中的PD7置为低电平,列中的其他三个置为高电平
PD_ODR=0x00;
delay(40);//这里要说明一下,由于矩阵键盘第一列和AD键盘共用一个IO口
//AD键盘的RC会影响IO口电平变化的时间,这里需要延时一段时间,让电容C放电完毕
if((PE_IDR&0x40)==0)//如果第一列的第四行按键被按下,则进入if语句内
{
delay(5);//延时一段时间,等待IO口电平稳定,即消抖
if((PE_IDR&0x40)==0)//再次判断按键是否被按下,避免干扰
{
num=12;//如果第一列的第四行按键被按下,则令num=12,即数码管显示为C
while((PE_IDR&0x40)==0);//如果按键没有松开,则等待
}
}
temp=PC_IDR&0xe0;
if(temp!
=0xe0)
{
delay(5);
temp=PC_IDR&0xe0;
if(temp!
=0xe0)
{
switch(temp)
{
case0xc0:
num=0;//如果temp的值为0xc0,则说明第1个按键被按下,下面的依次类推
break;
case0xa0:
num=4;
break;
case0x60:
num=8;
break;
}
while((PC_IDR&0xe0)!
=0xe0);
}
}
PE_ODR=0X24;
PD_ODR=0x80;
if((PE_IDR&0x40)==0)
{
num=13;
delay(5);
while((PE_IDR&0x40)==0);
}
temp=PC_IDR&0xe0;
if(temp!
=0xe0)
{
delay(5);
temp=PC_IDR&0xe0;
if(temp!
=0xe0)
{
switch(temp)
{
case0xc0:
num=1;
break;
case0xa0:
num=5;
break;
case0x60:
num=9;
break;
}
while((PC_IDR&0xe0)!
=0xe0);
}
}
PE_ODR=0X22;
PD_ODR=0x80;
if((PE_IDR&0x40)==0)
{
num=14;
delay(5);
while((PE_IDR&0x40)==0);
}
temp=PC_IDR&0xe0;
if(temp!
=0xe0)
{
delay(5);
temp=PC_IDR&0xe0;
if(temp!
=0xe0)
{
switch(temp)
{
case0xc0:
num=2;
break;
case0xa0:
num=6;
break;
case0x60:
num=10;
break;
}
while((PC_IDR&0xe0)!
=0xe0);
}
}
PE_ODR=0X06;
PD_ODR=0x80;
if((PE_IDR&0x40)==0)
{
num=15;
delay(5);
while((PE_IDR&0x40)==0);
}
temp=PC_IDR&0xe0;
if(temp!
=0xe0)
{
delay(5);
temp=PC_IDR&0xe0;
if(temp!
=0xe0)
{
switch(temp)
{
case0xc0:
num=3;
break;
case0xa0:
num=7;
break;
case0x60:
num=11;
break;
}
while((PC_IDR&0xe0)!
=0xe0);
}
}
returnnum;
}
voidmain()
{
ucharn;
init();
while
(1)
{
n=keys();//把函数keys()的返回值num赋给n
PB_ODR=table[n];
PC_ODR|=0x00;//选择第一个数码管
}
}
中断向量:
/*BASICINTERRUPTVECTORTABLEFORSTM8devices
*Copyright(c)2007STMicroelectronics
*/
typedefvoid@far(*interrupt_handler_t)(void);
structinterrupt_vector{
unsignedcharinterrupt_instruction;
interrupt_handler_tinterrupt_handler;
};
@far@interruptvoidNonHandledInterrupt(void)
{
/*inordertodetectunexpectedeventsduringdevelopment,
itisrecommendedtosetabreakpointonthefollowinginstruction
*/
return;
}
externvoid_stext();/*startuproutine*/
structinterrupt_vectorconst_vectab[]={
{0x82,(interrupt_handler_t)_stext},/*reset*/
{0x82,NonHandledInterrupt},/*trap*/
{0x82,NonHandledInterrupt},/*irq0*/
{0x82,NonHandledInterrupt},/*irq1*/
{0x82,NonHandledInterrupt},/*irq2*/
{0x82,NonHandledInterrupt},/*irq3*/
{0x82,NonHandledInterrupt},/*irq4*/
{0x82,NonHandledInterrupt},/*irq5*/
{0x82,NonHandledInterrupt},/*irq6*/
{0x82,NonHandledInterrupt},/*irq7*/
{0x82,NonHandledInterrupt},/*irq8*/
{0x82,NonHandledInterrupt},/*irq9*/
{0x82,NonHandledInterrupt},/*irq10*/
{0x82,NonHandledInterrupt},/*irq11*/
{0x82,NonHandledInterrupt},/*irq12*/
{0x82,NonHandledInterrupt},/*irq13*/
{0x82,NonHandledInterrupt},/*irq14*/
{0x82,NonHandledInterrupt},/*irq15*/
{0x82,NonHandledInterrupt},/*irq16*/
{0x82,NonHandledInterrupt},/*irq17*/
{0x82,NonHandledInterrupt},/*irq18*/
{0x82,NonHandledInterrupt},/*irq19*/
{0x82,NonHandledInterrupt},/*irq20*/
{0x82,NonHandledInterrupt},/*irq21*/
{0x82,NonHandledInterrupt},/*irq22*/
{0x82,NonHandledInterrupt},/*irq23*/
{0x82,NonHandledInterrupt},/*irq24*/
{0x82,NonHandledInterrupt},/*irq25*/
{0x82,NonHandledInterrupt},/*irq26*/
{0x82,NonHandledInterrupt},/*irq27*/
{0x82,NonHandledInterrupt},/*irq28*/
{0x82,NonHandledInterrupt},/*irq29*/
};
(3);名称:
定时器的使用
;描述:
数码管显示0~F,利用定时器使得1秒变换一次
;***********************************************************/
#include
#defineuintunsignedint
#defineucharunsignedchar
uchartable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uchart;
voidinit(void)
{
PB_DDR=0XFF;
PB_CR1=0XFF;
PB_CR2=0X00;
PC_DDR=0XFF;
PC_CR1=0XFF;
PC_CR2=0X00;
TIM2_EGR=0X01;//允许产生更新事件
TIM2_PSCR=0X01;//分频,使频率为1MHz
TIM2_ARRH=0XC3;//更新后计数器的值
TIM2_ARRL=0X50;
TIM2_CR1=0X05;//允许定时器工作
TIM2_IER=0X01;//允许更新中断
_asm("rim");//汇编语句,启动定时器
//注意!
使用定时器时要定义中断函数入口,详请打开main.c下面的stm8_interrupt_vector.c,请按照注释进行修改
}
voidmain(void)
{
uchari=0,j;
init();
while
(1)
{
PB_ODR=table[i];
PC_ODR=0x02;//选择第二个数码管显示
if(t==20)//这里设置50ms进入一次中断,t=20刚好为1秒
{
t=0;//t清零
i++;
if(i==16)
i=0;//由于数组中只有16个数,所以i最大只能为15,否则显示会出现乱码现象
}
}
}
@far@interruptvoidTIM2_UP_IRQHandler(void)//中断函数
{
TIM2_SR1=0x00;//进入中断时TIM2_SR1最低位会被硬件自动置一,进入中断后必须将其清零,否则无法再次产生中断
t++;//进入中断后t自加1
}
/*BASICINTERRUPTVECTORTABLEFORSTM8devices
*Copyright(c)2007STMicroelectronics
*/
typedefvoid@far(*interrupt_handler_t)(void);
structinterrupt_vector{
unsignedcharinterrupt_instruction;
interrupt_handler_tinterrupt_handler;
};
@far@interruptvoidNonHandledInterrupt(void)
{
/*inordertodetectunexpectedeventsduringdevelopment,
itisrecommendedtosetabreakpointonthefollowinginstruction
*/
return;
}
externvoid_stext();/*startuproutine*/
extern@far@interruptvoidTIM2_UP_IRQHandler(void);//使用定时器要加上这句话
structinterrupt_vectorconst_vectab[]={
{0x82,(interrupt_handler_t)_stext},/*reset*/
{0x82,NonHandledInterrupt},/*trap*/
{0x82,NonHandledInterrupt},/*irq0*/
{0x82,NonHandledInterrupt},/*irq1*/
{0x82,NonHandledInterrupt},/*irq2*/
{0x82,NonHandledInterrupt},/*irq3*/
{0x82,NonHandledInterrupt},/*irq4*/
{0x82,NonHandledInterrupt},/*irq5*/
{0x82,NonHandledInterrupt},/*irq6*/
{0x82,NonHandledInterrupt},/*irq7*/
{0x82,NonHandledInterrupt},/*irq8*/
{0x82,NonHandledInterrupt},/*irq9*/
{0x82,NonHandledInterrupt},/*irq10*/
{0x82,NonHandledInterrupt},/*irq11*/
{0x82,NonHandledInterrupt},/*irq12*/
{0x82,TIM2_UP_IRQHandler},/*irq13*///使用定时器要把这里的