stm8s的c语言编程例程

合集下载

STM8S_总汇编

STM8S_总汇编

不知是心血来潮,还是其它因素,突然又想起玩汇编语言了。

这几年也没少跟单片机打交道,包括51系列,430系列,ARM系列,但都是用C语言来开发。

不过由于使用C语言,实际上对这些CPU的了解还是不够深刻,当然除了51之外,因为那是我多年前曾经用汇编开发过的芯片。

尽管当今C语言已经在嵌入式产品的开发过程中成为主流,但我个人依然认为,要想真正了解CPU的特点,还得用汇编语言。

不知道这种观点是对还是错,也许是因为自己从硬件做起,写过机器码,用汇编语言做过优化,因此对汇编语音有一种特殊的偏爱。

51系列的芯片用多了,感觉有时写起程序来不太方便,因此总想寻找一些其它的8位单片机玩玩,正好手头有一个ST的三合一开发板,那是09年参加ST研讨会上买的,一直躺在那里,与其躺在那里,不如拿出来玩玩。

这几年,ST在国内推广STM32,力度不小,不过我一直没有用过,只是初步地看看资料。

原因在于在32位单片机方面,我一直在用Luminary公司的LM3S1138,感觉不错,一直都很顺利。

09年ST举办的研讨会上,ST除了介绍STM32外,也介绍了STM8,当时听了以后,觉得还行。

尤其是会上的低功耗演示给我留下了很深刻的印象。

基于这些,我决定好好地玩一下STM8芯片,并将玩的结果拿出来与大家共享。

STM8与汇编语言(2)第一次打开STM8的手册时发现,CPU中的寄存器只有6个,即A、X、Y、SP、PC 和CC。

这几个寄存器,看上去特象早年苹果机使用的微处理器6502。

在眼下都是多寄存器的RISC潮流下,不知ST推出的这种CPU架构有什么意图?这样的芯片能否与Microchip 或者Atmel的RISC结构的MCU竞争呢?在此我无意做评论,我只想了解这颗芯片。

通过仔细研究,我发现由于STM8采用了32位宽度的程序存储器结构,使得大部分的指令都能在一个周期内取出,并且采用了哈佛结构和流水线,相当多的指令也都是单周期完成的。

这样的话,虽然CPU是CISC架构的,但也基本上达到了单周期指令的效果,就像手册上说的,CPU的性能达到了20MISP◎24MHZ。

STM8单片机 UART发送完成中断C语言程序

STM8单片机 UART发送完成中断C语言程序

STM8S105发送完成中断#define TXRXBUF_SIZE 128uchar UART_RxTx[TXRXBUF_SIZE];volatile uchar UART_OutLen=0;volatile uchar TXRX_IndexR=0;volatile uchar TXRX_IndexW=0;void UART2_Init(void){//485 CS1控制PA_DDR |=1 << 6;PA_CR1 |=1 << 6;PA_CR2 &= ~( 1 <<6 );RS485_TX_EN=0; //设置为接收模式UART2_CR1=0x00;UART2_CR2=0x00;UART2_CR3=0x00;// 设置波特率,必须注意以下几点:// (1) 必须先写BRR2// (2) BRR1存放的是分频系数的第11位到第4位,// (3) BRR2存放的是分频系数的第15位到第12位,和第3位// 到第0位// 例如对于波特率位9600时,分频系数=2000000/9600=208// 对应的十六进制数为00D0,BBR1=0D,BBR2=00//UART2_BRR2=0x30;//UART2_BRR1=0xE8; //1K//UART2_BRR2=0x35;//UART2_BRR1=0x41; //1200UART2_BRR2=0x1B;UART2_BRR1=0xA0; //2400UART2_CR2=0x2c;//允许接收,发送,开接收中断//UART2_CR2=0x08; //发送使能}//------------方式二发送结束中断--------------------------------------#pragma vector=UART2_T_TC_vector__interrupt void UART2_T_TC(void){UART2_SR&= ~(1<<6); //清除送完成状态位if(UART_OutLen>0){UART2_DR=UART_RxTx[TXRX_IndexR];--UART_OutLen;if(++TXRX_IndexR >= TXRXBUF_SIZE){TXRX_IndexR=0;//FIFO回头}}else //发送结束{//UART_OutLen=TXRX_IndexR=TXRX_IndexW=0;//UART2_CR2 &= ~(1<<TCIEN);//关闭发送完成中断UART2_CR2 &= ~(1<<6);//关闭发送完成中断}}/************************************************************名称:Uart_IntSentBuf*功能:从串口UART0发送一组字节数据*入口参数:*p:待发的首个字节数据,len 发送个数*出口参数:返回1:发送成功* 返回0:发送失败*说明:在发送过程中,不阻塞CPU的运行。

stm8s的c语言编程例程

stm8s的c语言编程例程

实例一:控制灯的亮灭(或者蜂鸣器响,只要连接相应端口就可以了):#include "stm8s.h"//头文件#define ulong unsigned long///////////////////////////////////////////////////////////////////////////////void delay(ulong i){ulong j;for(j=0;j<i;j++){;}}////////////延时函数void main(void)////////////主函数{GPIO_DeInit(GPIOD);GPIO_Init(GPIOD, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);while(1){GPIO_WriteHigh(GPIOD, GPIO_PIN_1);delay(10000);delay(10000);delay(10000);GPIO_WriteLow(GPIOD, GPIO_PIN_1);delay(10000);delay(10000);delay(10000);}}第二步:控制灯按照一定的频率闪烁:频率可以使用时钟!Stm8启动时,主时钟默认为HSIRC时钟的8分频,HSIRC是可以提供一个低成本的16MHz 时钟源,#include "stm8s.h"//头文件void CLK_Configuration(void);void main(void)////////////主函数{GPIO_DeInit(GPIOD);GPIO_Init(GPIOD, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);CLK_Configuration();while(1){GPIO_WriteReverse(GPIOD, GPIO_PIN_1);}}void CLK_Configuration(void){/* Fmaster = 16MHz */CLK_HSIPrescalerConfig( CLK_PRESCALER_HISDIV1);}例题三:灯闪亮的同时蜂鸣器响#include "stm8s.h"//头文件#define ulong unsigned long///////////////////////////////////////////////////////////////////////////////void delay(ulong i){ulong j;for(j=0;j<i;j++){;}}////////////延时函数);void main(void)////////////主函数{GPIO_DeInit(GPIOD);GPIO_DeInit(GPIOB);GPIO_Init(GPIOD, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);GPIO_Init(GPIOB, GPIO_PIN_0,GPIO_MODE_OUT_PP_LOW_FAST );while(1){GPIO_WriteHigh(GPIOD, GPIO_PIN_1);delay(10000);delay(10000);GPIO_WriteLow(GPIOD, GPIO_PIN_1);delay(10000);delay(10000);GPIO_WriteHigh(GPIOB, GPIO_PIN_0);delay(10000);delay(10000);GPIO_WriteLow(GPIOB, GPIO_PIN_0);delay(10000);delay(10000);}}时钟控制器功能强大而且灵活易用。

ST单片机STM8S开发入门教程

ST单片机STM8S开发入门教程

ST单片机STM8S开发入门教程最近ST在国内大力推广他的8位高性价比单片机STM8S系列,感觉性能上还是非常不错的,网上稍微看了点资料,打算有机会还是学习一下,先入门为以后做好技术积累。

好了,长话短说。

手上拿到一套ST最近做活动赠送的三合一学习套件,上面包括STM32F小板、ST LINK小板、STM8S小板,做工很精致,相信很多朋友也收到了。

既然当初去申请了,人家也送了,总得把用起来吧,放着吃灰尘是很可惜的^_^ 。

好,步入正题,刚开始在论坛上逛了一圈,感觉STM8S的资料实在太少,都是官方的应用资料,没有什么入门介绍,连需要安装什么软件都搞不清楚。

偶的电脑光驱坏了,所以也读不出光盘里有什么东西,所以只能到处瞎摸,还是ourdev论坛好,嘿嘿,仔细看了几个帖子,总算明白大概是什么样的开发环境了。

用C语言开发STM8S,需要安装两个软件:1、STVD IDE开发环境;2、COSMIC for STM8 C编译器。

STVD可以到官网下载,下载地址:COSMIC 需要申请LICENSE,比较繁琐,刚好坛子有人传了一个免安装无限制版本的,偶就赶紧下载了,大家可以去下载,仅做为个人学习使用。

下载地址:软件下载后,只需安装STVD。

从上面地址下载的COSMIC不用安装,只要解压到硬盘即可。

后面建立工程的时候设置好路径即可。

下面一步一步开始啦~一、安装好STVD后,桌面上建立了两个快捷图标,ST Visual Develop就是STVD了。

ST Visual Programmer是编程软件,可以配合ST LINK对STM8S进行编程烧录。

二、双击运行ST Visual Develop,启动STVD开发环境。

执行Workspace,在New Workspace 窗口里选择Create workspace and projects,点击“确定”建立工作组和工程三、在Workspace 里输入Workspace名称,由于最终我们要测试一个现成的LED程序,所以偶写了led,随你喜欢了,呵呵。

STM8单片机的C语言编程基础与实践

STM8单片机的C语言编程基础与实践

/* MAIN.C file * * Copyright (c) 2002-2005 STMicroelectronics */
main() { while (1); } 而在 stm8_interrupt_vector.c 中,就是声明了对应该芯片的中断向量,如下所示: /* * */ typedef void @far (*interrupt_handler_t)(void); struct interrupt_vector { unsigned char interrupt_instruction; interrupt_handler_t interrupt_handler; }; @far @interrupt void NonHandledInterrupt (void) { /* in order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction BASIC INTERRUPT VECTOR TABLE FOR STM8 devices Copyright (c) 2007 STMicroelectronics
STM8 的 C 语言编程(2)-- 变量空间的分配
采用 C 这样的高级语言,其实可以不用关心变量在存储器空间中是如何具体分配的。但如果了解如何 分配,对编程还是有好处的,尤其是在调试时。 例如下面的程序定义了全局变量数组 buffer 和一个局部变量 i,在 RAM 中如何分配的呢? /* MAIN.C file * * Copyright (c) 2002-2005 STMicroelectronics */ unsigned char buffer[10]; // 定义全局变量

STM8S_汇编

STM8S_汇编

不知是心血来潮,还是其它因素,突然又想起玩汇编语言了。

这几年也没少跟单片机打交道,包括51系列,430系列,ARM系列,但都是用C语言来开发。

不过由于使用C语言,实际上对这些CPU的了解还是不够深刻,当然除了51之外,因为那是我多年前曾经用汇编开发过的芯片。

尽管当今C语言已经在嵌入式产品的开发过程中成为主流,但我个人依然认为,要想真正了解CPU的特点,还得用汇编语言。

不知道这种观点是对还是错,也许是因为自己从硬件做起,写过机器码,用汇编语言做过优化,因此对汇编语音有一种特殊的偏爱。

51系列的芯片用多了,感觉有时写起程序来不太方便,因此总想寻找一些其它的8位单片机玩玩,正好手头有一个ST的三合一开发板,那是09年参加ST研讨会上买的,一直躺在那里,与其躺在那里,不如拿出来玩玩。

这几年,ST在国内推广STM32,力度不小,不过我一直没有用过,只是初步地看看资料。

原因在于在32位单片机方面,我一直在用Luminary公司的LM3S1138,感觉不错,一直都很顺利。

09年ST举办的研讨会上,ST除了介绍STM32外,也介绍了STM8,当时听了以后,觉得还行。

尤其是会上的低功耗演示给我留下了很深刻的印象。

基于这些,我决定好好地玩一下STM8芯片,并将玩的结果拿出来与大家共享。

STM8与汇编语言(2)第一次打开STM8的手册时发现,CPU中的寄存器只有6个,即A、X、Y、SP、PC 和CC。

这几个寄存器,看上去特象早年苹果机使用的微处理器6502。

在眼下都是多寄存器的RISC潮流下,不知ST推出的这种CPU架构有什么意图?这样的芯片能否与Microchip 或者Atmel的RISC结构的MCU竞争呢?在此我无意做评论,我只想了解这颗芯片。

通过仔细研究,我发现由于STM8采用了32位宽度的程序存储器结构,使得大部分的指令都能在一个周期内取出,并且采用了哈佛结构和流水线,相当多的指令也都是单周期完成的。

这样的话,虽然CPU是CISC架构的,但也基本上达到了单周期指令的效果,就像手册上说的,CPU的性能达到了20MISP◎24MHZ。

STM8在IAR环境下的C语言开发

STM8在IAR环境下的C语言开发

STM8单片机在IAR环境下的C语言开发1、头文件搜索路径设置在工程管理窗口按右键,选择option,打开选项设置窗口如下选择C/C++ compiler选项,然后选择Preprocssor标签,在《Additional include directories 下输入要包含的搜索路径,这样在程序编译时,编译器会自动到该目录下搜索头文件。

2、单片机类型的选择在工程管理窗口按右键选择option,选择<General Options>选项,然后再Target中选择相应的单片机型号。

3、Printf函数的使用要使用printf函数,需要在工程管理窗口按右键选择《option》,选择<General Options>选项,然后选择《library Configuration》标签,在《library》中选择Full,如下图所示。

对于程序空间非常小的单片机,如STM8S003只有8K的程序空间,如果使用全功能的printf函数,则程序编译后代码空间不足,此时应不使用printf或者使用Tiny版本的printf,选择Library Options标签,选择Printf formatter 为tiny。

为了能够使用printf,在程序中需要增加如下代码#include "stdio.h"//------------------------------------------------------------------------------// 使用Printf//------------------------------------------------------------------------------// 又有STM8S003只有8K的内存,使用完整的printf则程序空间不足,必须使用tiny的printf// 因此在工程的选项中Library configuration选择Full,在Library option 中选择tiny#ifdef __GNUC__#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)#endifPUTCHAR_PROTOTYPE{//发送数据代码UART1->DR = ch;while(UART1_GetFlagStatus(UART1_FLAG_TXE) == RESET);return ch;}4、查看程序编译后的代码大小在工程的目录下有《Debug》和《Release》目录,目中中的《List》目录中有个扩展名为map的文件,文件名为工程名,打开该文件,可以看到程序编译后的代码大小。

STM8的C语言编程-RAM中变量分配

STM8的C语言编程-RAM中变量分配

STM8的C语言编程(2)--RAM中变量分配采用C这样的高级语言,其实可以不用关心变量在存储器空间中是如何具体分配的。

但如果了解如何分配,对编程还是有好处的,尤其是在调试时。

例如下面的程序定义了全局变量数组buffer和一个局部变量i,在RAM中如何分配的呢?/* MAIN.C file** Copyright (c) 2002-2005 STMicroelectronics*/unsigned char buffer[10]; // 定义全局变量main(){unsigned char i; // 定义局部变量for(i=0;i<10;i++){buffer[i] = 0x55;}}我们可以通过DEBUG中的反汇编窗口,看到如下的对应代码:从这段代码中可以看到,全局变量buffer被分配到空间从地址0000H到0009H。

而局部变量i则在堆栈空间中分配,通过PUSH A指令,将堆栈指针减1,腾出一个字节的空间,而SP+1指向的空间就是分配给局部变量使用的空间。

由此可以得出初步的结论,对于全局变量,内存分配是从低地址0000H开始向上分配的。

而局部变量则是在堆栈空间中分配。

1 / 2另外从上一篇文章中,可以知道堆栈指针初始化时为0FFFH。

而根据PUSH指令的定义,当压栈后堆栈指针减1。

因此堆栈是从上往下使用的。

因此根据内存分配和堆栈使用规则,我们在程序设计时,不能定义过多的变量,免得没有空间给堆栈使用。

换句话说,当定义变量时,一定要考虑到堆栈空间,尤其是那些复杂的系统,程序调用层数多,这样就会占用大量的堆栈空间。

总之,在单片机的程序设计时,由于RAM空间非常有限,要充分考虑到全局变量、局部变量、程序调用层数和中断服务调用对空间的占用。

友情提示:范文可能无法思考和涵盖全面,供参考!最好找专业人士起草或审核后使用,感谢您的下载!。

stm8s绝对值算法

stm8s绝对值算法

STM8S是一款基于8051内核的单片机,如果你想在STM8S上实现绝对值算法,你需要考虑几个关键步骤。

以下是一个基本的绝对值算法的步骤:1. 定义输入和输出:首先,你需要定义一个输入变量和一个输出变量。

输入变量将包含你想要计算其绝对值的值,而输出变量将存储计算结果。

2. 检查输入值的符号:要找到一个数的绝对值,你需要先确定它是正数还是负数。

这可以通过检查输入值的符号位来实现。

在二进制中,负数的最高位(符号位)是1,而正数和零的最高位是0。

3. 应用绝对值算法:一旦你确定了输入值的符号,你就可以应用绝对值算法了。

如果输入是负数,你需要将其值取反(即将其每个位上的1变为0,0变为1),然后加1。

这会得到输入值的绝对值。

如果输入是正数或零,其绝对值就是它本身,不需要进行任何更改。

4. 存储和返回结果:最后,将计算得到的绝对值存储在输出变量中,并返回该值。

以下是一个简单的C语言实现这个算法的例子:```c#include <stdio.h>int abs_value(int num) {int result;if (num < 0) {// 如果输入是负数,取反并加1得到绝对值num = ~num + 1;}result = num;return result;}int main() {int num = -10; // 你可以更改这个值来测试不同的输入printf("The absolute value of %d is %d.\n", num, abs_value(num));return 0;}```这个程序定义了一个函数`abs_value`,它接受一个整数作为输入,并返回该整数的绝对值。

主函数`main`中调用这个函数并打印结果。

你可以修改`num`的值来测试不同的输入。

stm8C语言例程

stm8C语言例程

(1);名称:流水灯;描述 : ;先从上至下点亮所有的LED,再逐个点亮单个LED;***********************************************************/#include "stm8s105s4.h"#define uchar unsigned char#define uint unsigned intuchar table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //存放点亮单个LED的代码void DelayMS(uint s) //延时子函数,约延时1ms{uint i;for(s;s>0;s--)for(i=0;i<500;i++);}void init(void) //stm8初始化函数{PB_DDR = 0xff;PB_CR1 = 0xff; // 将PB设置成推挽输出PB_CR2 = 0x00;CLK_SWR = 0xE1; //选部高速时钟作为主时钟CLK_CKDIVR = 0x08; //将CPU主频设置为2M(STM8默认的就是部高速时钟的八分频,即2MH,这里只是告诉大家设置方法)}void main(){uchar i;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 ,从上至下依次点亮LEDDelayMS(500);}}}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void far (*interrupt_handler_t)(void);struct interrupt_vector {unsigned char interrupt_instruction;interrupt_handler_t interrupt_handler;};far interrupt void NonHandledInterrupt (void){/* in order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction */return;}extern void _stext(); /* startup routine */struct interrupt_vector const _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 <stm8s105s4.h>#define uint unsigned int#define uchar unsigned charuchartable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x8 6,0x8e};uchar num;void delay(uchar a){uchar i;for(a;a>0;a--)for(i=0;i<255;i++);}void init(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资料***//***扫描方式也可为行输出,列输入,读者可以自己尝试着修改***/uchar keys(void) //此子函数看起来很长,实则只有前面一截容,下面的“同理可得”{uchar temp;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,即数码管显示为Cwhile((PE_IDR&0x40)==0); //如果按键没有松开,则等待}}temp=PC_IDR&0xe0;if(temp!=0xe0){delay(5);temp=PC_IDR&0xe0;if(temp!=0xe0){switch(temp){case 0xc0:num=0; //如果temp的值为0xc0,则说明第1个按键被按下,下面的依次类推break;case 0xa0:num=4;break;case 0x60: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){case 0xc0:num=1;break;case 0xa0:num=5;break;case 0x60: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){case 0xc0:num=2;break;case 0xa0:num=6;break;case 0x60: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){case 0xc0:num=3;break;case 0xa0:num=7;break;case 0x60:num=11;break;}while((PC_IDR&0xe0)!=0xe0);}}return num;}void main(){uchar n;init();while(1){n=keys(); //把函数keys()的返回值num赋给nPB_ODR=table[n];PC_ODR|=0x00; //选择第一个数码管}}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void far (*interrupt_handler_t)(void);struct interrupt_vector {unsigned char interrupt_instruction;interrupt_handler_t interrupt_handler;};far interrupt void NonHandledInterrupt (void){/* in order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction */return;}extern void _stext(); /* startup routine */struct interrupt_vector const _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 <stm8s105s4.h>#define uint unsigned int#define uchar unsigned charuchartable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x8 6,0x8e};uchar t;void init(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; //分频,使频率为1MHzTIM2_ARRH=0XC3; //更新后计数器的值TIM2_ARRL=0X50;TIM2_CR1=0X05; //允许定时器工作TIM2_IER=0X01; //允许更新中断_asm("rim"); //汇编语句,启动定时器//注意!使用定时器时要定义中断函数入口,详请打开main.c下面的stm8_interrupt_vector.c,请按照注释进行修改}void main(void){uchar i=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 interrupt void TIM2_UP_IRQHandler (void) //中断函数{TIM2_SR1 = 0x00; //进入中断时TIM2_SR1最低位会被硬件自动置一,进入中断后必须将其清零,否则无法再次产生中断t++; //进入中断后t自加1}/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void far (*interrupt_handler_t)(void);struct interrupt_vector {unsigned char interrupt_instruction;interrupt_handler_t interrupt_handler;};far interrupt void NonHandledInterrupt (void){/* in order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction*/return;}extern void _stext(); /* startup routine */extern far interrupt void TIM2_UP_IRQHandler (void); //使用定时器要加上这句话struct interrupt_vector const _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 */ //使用定时器要把这里的“NonHandledInterrupt”改为“TIM2_UP_IRQHandler”,即中断函数名{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)(4):蜂鸣器:定时器方式;名称 :蜂鸣器;描述 : 利用定时器产生;***********************************************************/#include <stm8s105s4.h>#define uchar unsigned char_Bool beep PD_ODR:4;uchar t2,t3;void init(void){PD_DDR=0X10;PD_CR1=0X10; //连接蜂鸣器的IO口初始化PD_CR2=0X00;PD_ODR|=0x10;TIM2_EGR=0X01; //允许产生更新事件TIM2_PSCR=0X01; //分频,使频率为1MHzTIM2_ARRH=0XC3; //更新后计数器的值TIM2_ARRL=0X50; //定时50ms,用于控制发声时间TIM2_CR1=0X05; //允许定时器工作TIM2_IER=0X01; //允许更新中断TIM3_EGR=0X01; //允许产生更新事件TIM3_PSCR=0X01; //分频,使频率为1MHzTIM3_ARRH=0X00; //更新后计数器的值TIM3_ARRL=0Xfa; //这里定时0.25ms,用于产生所需的频率TIM3_CR1=0X05; //允许定时器工作TIM3_IER=0X01; //允许更新中断_asm("rim"); //汇编语句,启动定时器}void delay(uchar s){uchar i;for(s;s>0;s--)for(i=0;i<250;i++);}void main(){init();while(1){if(t3%2==0) //前一秒产生2KHz频率的声音beep=1; //定时器3时间0.25ms,一个周期0.5ms,故频率为2Kelsebeep=0;while(t2>=20&&t2<40) //第二秒产生1KHz频率声音 {if(t3%4<2)beep=1;elsebeep=0;}while(t2>=40&&t2<60) //第三秒产生500Hz频率声音 {if(t3%8<4)beep=1;elsebeep=0;}if(t2>=60)t2=0;if(t3==8)t3=0;}}far interrupt void TIM2_UP_IRQHandler (void) //定时器2中断函数{TIM2_SR1 = 0x00; //清零TIM2_SR1 t2++;}far interrupt void TIM3_UP_IRQHandler (void) //定时器三中断函数{TIM3_SR1 = 0x00; //清零TIM2_SR1 t3++;}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void far (*interrupt_handler_t)(void);struct interrupt_vector {unsigned char interrupt_instruction;interrupt_handler_t interrupt_handler;far interrupt void NonHandledInterrupt (void){/* in order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction */return;}extern void _stext(); /* startup routine */extern far interrupt void TIM2_UP_IRQHandler (void);extern far interrupt void TIM3_UP_IRQHandler (void);struct interrupt_vector const _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 */{0x82, NonHandledInterrupt}, /* irq14 */{0x82, TIM3_UP_IRQHandler}, /* 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 */(5)蜂鸣器:stm8BEEP方式;名称:STM8自带蜂鸣器使用;描述 : ;注!此功能需用ST Link辅助设置,协会实验板无常工作,这里仅作参考;***********************************************************/#include <stm8s105s4.h>#define uchar unsigned charuchar t;void init(void) //初始化函数{CLK_ICKR|=0x08; // 打开芯片部的低速振荡器LSIwhile((CLK_ICKR&0x10)==0); // 等待振荡器稳定TIM2_EGR=0X01; //允许产生更新事件TIM2_PSCR=0X01; //分频,使频率为1MHzTIM2_ARRH=0XC3; //更新后计数器的值TIM2_ARRL=0X50;TIM2_CR1=0X05; //允许定时器工作TIM2_IER=0X01; //允许更新中断_asm("rim"); //汇编语句,启动定时器}void main(){uchar i;init();while(1){BEEP_CSR=0x26; //一秒2KHzwhile((t>=20)&&(t<40))BEEP_CSR=0x2e; //一秒1KHzwhile((t>=40)&&(t<60))BEEP_CSR=0x3e; //一秒500Hzwhile((t>=60)&&(t<80))BEEP_CSR&=0xdf; //一秒关闭if(t>=80)t=0;}}far interrupt void TIM2_UP_IRQHandler (void) //中断函数{TIM2_SR1 = 0x00;t++;}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void far (*interrupt_handler_t)(void);struct interrupt_vector {unsigned char interrupt_instruction;interrupt_handler_t interrupt_handler;};far interrupt void NonHandledInterrupt (void){/* in order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction */return;}extern void _stext(); /* startup routine */extern far interrupt void TIM2_UP_IRQHandler (void);struct interrupt_vector const _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 */{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 */};/*Stm8BEEP:*//******************************************************************************** * file stm8s_beep.c* brief This file contains all the functions for the BEEP peripheral.* author STMicroelectronics - MCD Application Team* version V1.1.1* date 06/05/2009****************************************************************************** ** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>* image html logo.bmp****************************************************************************** *//* Includes ------------------------------------------------------------------*/ #include "stm8s_beep.h"/* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//* Public functions ----------------------------------------------------------*//*** addtogroup BEEP_Public_Functions* {*//*** brief Deinitializes the BEEP peripheral registers to their default reset* values.* par Parameters:* None* retval None*/void BEEP_DeInit(void){BEEP->CSR = BEEP_CSR_RESET_VALUE;}/*** brief Initializes the BEEP function according to the specified parameters. * param[in] BEEP_Frequency Frequency selection.* can be one of the values of ref BEEP_Frequency_TypeDef.* retval None* par Required preconditions:* The LS RC calibration must be performed before calling this function.*/void BEEP_Init(BEEP_Frequency_TypeDef BEEP_Frequency){/* Check parameter */assert_param(IS_BEEP_FREQUENCY_OK(BEEP_Frequency));/* Set a default calibration value if no calibration is done */if ((BEEP->CSR & BEEP_CSR_BEEPDIV) == BEEP_CSR_BEEPDIV){BEEP->CSR &= (u8)(~BEEP_CSR_BEEPDIV); /* Clear bits */BEEP->CSR |= BEEP_CALIBRATION_DEFAULT;}/* Select the output frequency */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPSEL);BEEP->CSR |= (u8)(BEEP_Frequency);}/*** brief Enable or disable the BEEP function.* param[in] NewState Indicates the new state of the BEEP function.* retval None* par Required preconditions:* Initialisation of BEEP and LS RC calibration must be done before.*/void BEEP_Cmd(FunctionalState NewState){if (NewState != DISABLE){/* Enable the BEEP peripheral */BEEP->CSR |= BEEP_CSR_BEEPEN;}else{/* Disable the BEEP peripheral */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPEN);}}/*** brief Update CSR register with the measured LSI frequency.* par Note on the APR calculation:* A is the integer part of LSIFreqkHz/4 and x the decimal part.* x <= A/(1+2A) is equivalent to A >= x(1+2A) and also to 4A >= 4x(1+2A) [F1] * but we know that A + x = LSIFreqkHz/4 ==> 4x = LSIFreqkHz-4A* so [F1] can be written :* 4A >= (LSIFreqkHz-4A)(1+2A)* param[in] LSIFreqHz Low Speed RC frequency measured by timer (in Hz).* retval None* par Required preconditions:* - BEEP must be disabled to avoid unwanted interrupts.*/void BEEP_LSICalibrationConfig(u32 LSIFreqHz){u16 lsifreqkhz;u16 A;/* Check parameter */assert_param(IS_LSI_FREQUENCY_OK(LSIFreqHz));lsifreqkhz = (u16)(LSIFreqHz / 1000); /* Converts value in kHz *//* Calculation of BEEPER calibration value */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPDIV); /* Clear bits */A = (u16)(lsifreqkhz >> 3U); /* Division by 8, keep integer part only */if ((8U * A) >= ((lsifreqkhz - (8U * A)) * (1U + (2U * A)))){BEEP->CSR |= (u8)(A - 2U);}else{BEEP->CSR |= (u8)(A - 1U);}/* Set the AWU MR bit to load the new value to the prescalers */AWU->CSR |= AWU_CSR_MR;}/*** }*//******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ //st visual programmer 把Option Bytes 里//AFR7改为"Port D4 Alternate Function =Beep" ,否则没有声音void main ( void ){CLK_INIT();//设置外部时钟GPIO_INIT();//初始化IOFLASH_INIT();//初始化FLASH//PD4第二功能脚不是beep功能,就强制写成beepif(FLASH_ReadOptionByte(0x4803) != 0x807F){FLASH_ProgramOptionByte(0x4803,0x80);//将PD4的第二功能脚写成beepWWDG->CR = 0x80;//复位stm8}BEEP_LSICalibrationConfig(128000);BEEP_Init(BEEP_FREQUENCY_2KHZ);BEEP_Cmd(ENABLE);while(1){delay(1000);BEEP_Cmd(ENABLE);delay(1000);BEEP_Cmd(DISABLE);}};名称 :点阵;描述 : 循环显示I LOVE(心形) U;说明:由于这里将心形采用动态形式显示,使得显示数组较多,前三个一样的数组是为了延长“I”的显示时间,这样显示时间才协调后三个数组同理,中间的九个数组是使得心形有动态效果的,这里看起来很复杂,实则读者在这里只要掌握595的使用就可以很容易理解了,595的使用涉及到操作时序,需要看懂时序图,这是很重要的;***********************************************************/#include <stm8s105s4.h>#define uchar unsigned char#define uint unsigned int_Bool E PG_ODR:0; //注意这里开始引入位定义,相当于51里的sbit E=PG0;这是stm8的位定义形式_Bool RCLK PD_ODR:4;_Bool SRCLK PD_ODR:5;_Bool SER PD_ODR:6;uchar a,b;uchar table[14][8]={{0xff,0x83,0xef,0xef,0xef,0xef,0x83,0xff},{0xff,0x83,0xef,0xef,0xef,0xef,0x83,0xff},{0xff,0x83,0xef,0xef,0xef,0xef,0x83,0xff},{0xff,0xff,0xef,0xff,0xff,0xff,0xff,0xff},{0xff,0x93,0xef,0xff,0xff,0xff,0xff,0xff},{0xff,0x93,0x6d,0xff,0xff,0xff,0xff,0xff},{0xff,0x93,0x6d,0x7d,0xff,0xff,0xff,0xff},{0xff,0x93,0x6d,0x7d,0xbb,0xff,0xff,0xff},{0xff,0x93,0x6d,0x7d,0xbb,0xd7,0xff,0xff},{0xff,0x93,0x6d,0x7d,0xbb,0xd7,0xef,0xff},{0xff,0x93,0x6d,0x7d,0xbb,0xd7,0xef,0xff},{0xff,0xbb,0xbb,0xbb,0xbb,0xbb,0xc7,0xff},{0xff,0xbb,0xbb,0xbb,0xbb,0xbb,0xc7,0xff},{0xff,0xbb,0xbb,0xbb,0xbb,0xbb,0xc7,0xff}};//存放了显示的代码void delay(uint s){uchar i;for(s;s>0;s--)for(i=0;i<200;i++);}void init(void) //初始化函数,PC是用来控制138以驱动点阵的行{PG_DDR=0x01;PG_CR1=0x01;PG_CR2=0x00;PD_DDR=0x70;PD_CR1=0x70;PD_CR2=0x00;PC_DDR=0x0f;PC_CR1=0x0f;PC_CR2=0x00;}void display(void) //显示子函数{uchar m,n,p,q;E=1; //先关闭595(赋值时会影响显示效果)m=table[a][b]; //将要显示的table[a][b]赋值给mfor(q=0;q<8;q++){p=0;if((m&0x80)==0x80)p=1; //这三句的意思是如果m的最高位是1,则p=1,否则为0,就是把m最高位赋值给pSER=p; //把p输入595输入口SRCLK=0;RCLK=1;if(1);SRCLK=1;RCLK=0; //以上语句涉及 595的操作时序,请参考595芯片资料m=(m<<1);}E=0; //赋值完后打开595}void main(){uint i,j;init();while(1){for(a=0;a<14;a++) //有14个数组要传送{for(i=0;i<10;i++) //每个数组扫描10次,这样才能看清楚{for(b=0;b<8;b++) //每个数组有8个数{display();PC_ODR=b*2; //让138和595同步delay(2); //延时一会,以使显示清楚,延时不能太长,太长会看到闪烁,也不能太短,太短显示不清楚}}}delay(1000); //为了使得看起来是I LOVE U是一个周期,这里循环一次后,延时1秒}}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void far (*interrupt_handler_t)(void);struct interrupt_vector {unsigned char interrupt_instruction;interrupt_handler_t interrupt_handler;};far interrupt void NonHandledInterrupt (void){/* in order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction*/return;}extern void _stext(); /* startup routine */struct interrupt_vector const _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 */};(7):1602;名称 :1602液晶屏;描述 : 利用1602显示”today···,I am very happy,以及电协www.gdutelc.,welcome to LCD “;***********************************************************/#include <stm8s105s4.h>#define uchar unsigned char#define uint unsigned intuchar table0[]="today...";uchar table1[]="I am very happy!";uchar table2[]=".gdutelc.";uchar table3[]="Welcome to LCD";_Bool RS PA_ODR:4;_Bool RW PA_ODR:5;_Bool E PA_ODR:6;void write_(uchar );void delay(uint a){uchar i;for(a;a>0;a--)for(i=0;i<250;i++);}void init_stm8(void){PA_DDR=0x70;PA_CR1=0x70;PA_CR2=0x00;PB_DDR=0xff;PB_CR1=0xff;PB_CR2=0x00;}void init_1602(void){write_(0x38); //显示模式设置write_(0x0c); //开显示,不显示光标write_(0x06); //地址指针自动加一write_(0x01); //清屏write_(0x80+0x04); //指针指向第一行第四格RW=0; //因只涉及向1602写数据,不涉及读,写的时候RW引脚都为低电平,故将RW置低}//写指令子函数,涉及1602时序,请参考1602资料void write_(uchar ){RS=0;E=0;PB_ODR=;delay(2);E=1;E=0;}//写数据子函数,写指令和数据区别在RS电平的高低void write_data(uchar data){RS=1;E=0;。

STM8的C语言编程(3) ―― GPIO输出和输入

STM8的C语言编程(3) ―― GPIO输出和输入

STM8的C语言编程(3)―― GPIO输出和输入今天要进行的实验,是利用GPIO进行输入和输出。

在ST的三合一开发板上,按键接在GPIO的PD7上,LED接在GPIO的PD3上,因此我们要将GPIO的PD7初始化成输入,PD3初始化成输出。

关于GPIO的引脚设置,主要是要初始化方向寄存器DDR,控制寄存器1(CR 1)和控制寄存器2(CR2),寄存器的每一位对应GPIO的每一个引脚。

具体的设置功能定义如下:DDR CR1 CR2 引脚设置0 0 0 悬浮输入0 0 1 上拉输入0 1 0 中断悬浮输入0 1 1 中断上拉输入1 0 0 开漏输出1 1 0 推挽输出1 X 1 输出(最快速度为10MHZ)另外,输出引脚对应的寄存器为ODR,输入引脚对应的寄存器为IDR。

下面的程序是检测按键的状态,当按键按下时,点亮LED,当按键抬起时,熄灭LED。

同样也是利用ST的开发工具,先生成一个C语言程序的框架,然后修改其中的main.c,修改后的代码如下。

编译通过后,下载到开发板,运行程序,按下按键,LED就点亮,抬起按键,L ED就熄灭了。

另外,要注意,将STM8S207C_S.h拷贝到当前项目的目录下。

// 程序描述:检测开发板上的按键,若按下,则点亮LED,若抬起,则熄灭LE D// 按键接在MCU的GPIO的PD7上// LED接在MCU的GPIO的PD3上#include "STM8S207C_S.h"main(){PD_DDR = 0x08;PD_CR1 = 0x08; // 将PD3设置成推挽输出PD_CR2 = 0x00;while(1) // 进入无限循环{if((PD_IDR & 0x80) == 0x80) // 读入PD7的引脚信号{PD_ODR = PD_ODR & 0xF7; // 如果PD7为1,则将PD3的输出设置成0,熄灭LED}else{PD_ODR = PD_ODR | 0x08; // 否则,将PD3的输出设置成1,点亮L ED}}}。

STM8S_汇编

STM8S_汇编

STM8S_汇编不知是心血来潮,还是其它因素,突然又想起玩汇编语言了。

这几年也没少跟单片机打交道,包括51系列,430系列,ARM系列,但都是用C语言来开发。

不过由于使用C语言,实际上对这些CPU的了解还是不够深刻,当然除了51之外,因为那是我多年前曾经用汇编开发过的芯片。

尽管当今C语言已经在嵌入式产品的开发过程中成为主流,但我个人依然认为,要想真正了解CPU的特点,还得用汇编语言。

不知道这种观点是对还是错,也许是因为自己从硬件做起,写过机器码,用汇编语言做过优化,因此对汇编语音有一种特殊的偏爱。

51系列的芯片用多了,感觉有时写起程序来不太方便,因此总想寻找一些其它的8位单片机玩玩,正好手头有一个ST的三合一开发板,那是09年参加ST研讨会上买的,一直躺在那里,与其躺在那里,不如拿出来玩玩。

这几年,ST在国内推广STM32,力度不小,不过我一直没有用过,只是初步地看看资料。

原因在于在32位单片机方面,我一直在用Luminary公司的LM3S1138,感觉不错,一直都很顺利。

09年ST举办的研讨会上,ST除了介绍STM32外,也介绍了STM8,当时听了以后,觉得还行。

尤其是会上的低功耗演示给我留下了很深刻的印象。

基于这些,我决定好好地玩一下STM8芯片,并将玩的结果拿出来与大家共享。

STM8与汇编语言(2)第一次打开STM8的手册时发现,CPU中的寄存器只有6个,即A、X、Y、SP、PC 和CC。

这几个寄存器,看上去特象早年苹果机使用的微处理器6502。

在眼下都是多寄存器的RISC潮流下,不知ST推出的这种CPU架构有什么意图?这样的芯片能否与Microchip 或者Atmel的RISC结构的MCU竞争呢?在此我无意做评论,我只想了解这颗芯片。

通过仔细研究,我发现由于STM8采用了32位宽度的程序存储器结构,使得大部分的指令都能在一个周期内取出,并且采用了哈佛结构和流水线,相当多的指令也都是单周期完成的。

stm8C语言例程

stm8C语言例程

;描述 : ;先从上至下点亮所有的LED,再逐个点亮单个LED;***********************************************************/#include ""#define uchar unsigned char#define uint unsigned intuchar table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; * @author STMicroelectronics - MCD Application Team* @version * @date 06/05/2009******************************************************************************** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>* @image html*******************************************************************************//* Includes ------------------------------------------------------------------*/#include ""/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//* Public functions ----------------------------------------------------------*//*** @addtogroup BEEP_Public_Functions* @{*//*** @brief Deinitializes the BEEP peripheral registers to their default reset* values.* @par Parameters:* None* @retval None*/void BEEP_DeInit(void){BEEP->CSR = BEEP_CSR_RESET_VALUE;}/*** @brief Initializes the BEEP function according to the specified parameters. * @param[in] BEEP_Frequency Frequency selection.* can be one of the values of @ref BEEP_Frequency_TypeDef.* @retval None* @par Required preconditions:* The LS RC calibration must be performed before calling this function.*/void BEEP_Init(BEEP_Frequency_TypeDef BEEP_Frequency){/* Check parameter */assert_param(IS_BEEP_FREQUENCY_OK(BEEP_Frequency));/* Set a default calibration value if no calibration is done */if ((BEEP->CSR & BEEP_CSR_BEEPDIV) == BEEP_CSR_BEEPDIV){BEEP->CSR &= (u8)(~BEEP_CSR_BEEPDIV); /* Clear bits */BEEP->CSR |= BEEP_CALIBRATION_DEFAULT;}/* Select the output frequency */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPSEL);BEEP->CSR |= (u8)(BEEP_Frequency);}/*** @brief Enable or disable the BEEP function.* @param[in] NewState Indicates the new state of the BEEP function.* @retval None* @par Required preconditions:* Initialisation of BEEP and LS RC calibration must be done before.*/void BEEP_Cmd(FunctionalState NewState){if (NewState != DISABLE){/* Enable the BEEP peripheral */BEEP->CSR |= BEEP_CSR_BEEPEN;}else{/* Disable the BEEP peripheral */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPEN);}/*** @brief Update CSR register with the measured LSI frequency.* @par Note on the APR calculation:* A is the integer part of LSIFreqkHz/4 and x the decimal part.* x <= A/(1+2A) is equivalent to A >= x(1+2A) and also to 4A >= 4x(1+2A) [F1] * but we know that A + x = LSIFreqkHz/4 ==> 4x = LSIFreqkHz-4A* so [F1] can be written :* 4A >= (LSIFreqkHz-4A)(1+2A)* @param[in] LSIFreqHz Low Speed RC frequency measured by timer (in Hz).* @retval None* @par Required preconditions:* - BEEP must be disabled to avoid unwanted interrupts.*/void BEEP_LSICalibrationConfig(u32 LSIFreqHz){u16 lsifreqkhz;u16 A;/* Check parameter */assert_param(IS_LSI_FREQUENCY_OK(LSIFreqHz));lsifreqkhz = (u16)(LSIFreqHz / 1000); /* Converts value in kHz *//* Calculation of BEEPER calibration value */BEEP->CSR &= (u8)(~BEEP_CSR_BEEPDIV); /* Clear bits */A = (u16)(lsifreqkhz >> 3U); /* Division by 8, keep integer part only */if ((8U * A) >= ((lsifreqkhz - (8U * A)) * (1U + (2U * A)))){BEEP->CSR |= (u8)(A - 2U);}else{BEEP->CSR |= (u8)(A - 1U);}/* Set the AWU MR bit to load the new value to the prescalers */AWU->CSR |= AWU_CSR_MR;}/***//******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ .";uchar table1[]="I am very happy!";uchar table2[]="";uchar table3[]="Welcome to LCD";_Bool RS @PA_ODR:4;_Bool RW @PA_ODR:5;_Bool E @PA_ODR:6;void write_com(uchar com);void delay(uint a){uchar i;for(a;a>0;a--)for(i=0;i<250;i++);}void init_stm8(void){PA_DDR=0x70;PA_CR1=0x70;PA_CR2=0x00;PB_DDR=0xff;PB_CR1=0xff;PB_CR2=0x00;}void init_1602(void){write_com(0x38); //显示模式设置write_com(0x0c); //开显示,不显示光标write_com(0x06); //地址指针自动加一write_com(0x01); //清屏write_com(0x80+0x04); //指针指向第一行第四格RW=0; //因只涉及向1602写数据,不涉及读,写的时候RW引脚都为低电平,故将RW置低}//写指令子函数,涉及1602时序,请参考1602资料void write_com(uchar com){RS=0;E=0;PB_ODR=com;delay(2);E=0;}//写数据子函数,写指令和数据区别在RS电平的高低void write_data(uchar data){RS=1;E=0;PB_ODR=data;delay(2);E=1;E=0;}//显示子函数void display(uchar *s){while(*s>0) //在有n个字符的字符组中有n+1字节,最后一字节为0,故这里就是把所有字符显示完后退出显示{write_data(*s++); //显示指针×s所指地址的字符delay(50);}}void main(){uchar i;init_stm8();while(1){init_1602(); //初始化1602display(table0); //显示today···write_com(0x80+0x40); //将地址指针移到第二行display(table1); //显示table1中的字符delay(1000); //延时一段时间write_com(0x01); //清屏write_com(0x38); //显示模式设置write_com(0x80+0x10); //地址指针移到第一行第17列中display(table2);write_com(0x80+0x40+0x10); //地址指针移到第二行第17列中display(table3);for(i=0;i<15;i++) //整屏左移15行{write_com(0x18); //整屏向左移delay(200);delay(2000);}}中断向量:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void @far (*interrupt_handler_t)(void);struct interrupt_vector {unsigned char interrupt_instruction;interrupt_handler_t interrupt_handler;};@far @interrupt void NonHandledInterrupt (void){/* in order to detect unexpected events during development,it is recommended to set a breakpoint on the following instruction */return;}extern void _stext(); /* startup routine */struct interrupt_vector const _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 */ };。

STM8S105K4简单历程

STM8S105K4简单历程
作为一个初学STM8 C语言者。慢慢摸索了好多天,发现网上的例子很难看懂(基础差,要不就是库函数),故整理了一下最近我编的几个列子,只适合初学STM8 C的同学。大神们看到了可以给点建议。我用的是STM8S105K4。下面几个列子是控制PA口的一个管脚输出高电平。我使用了三种方式进行控制。1、延时函数。2、定时器。3、定时器中断。希望初学者有些帮助。
{0x82, NonHandledInterrupt}, /* irq28 */
{0x82, NonHandledInterrupt}, /* irq29 */
};
希望对大家有所帮助。
TIM4_PSCR=0X07;//计数器周期63us。
TIM4_ARR=125;//计数值,8ms。
TIM4_CNTR=0;//计数器初值。
TIM4_SR=0;//清除更新标志。
TIM4_CR1=0X01;//启动定时器。
_asm("rim");//允许CPU全局中断。
TIM4_IER=0x01;//使能tim4中断。
{0x82, NonHandledInterrupt}, /* irq15 */
{0x82, NonHandledInterrupt}, /* irq16 */
{0x82, NonHandledInterrupt}, /* irq17 */
{0x82, NonHandledInterrupt}, /* irq18 */
*/
typedef void @far (*interrupt_handler_t)(void);
struct interrupt_vector {
unsigned char interrupt_instruction;

基于STM8的电子琴完整代码 (IAR C语言)

基于STM8的电子琴完整代码 (IAR  C语言)

#include"iostm8s105c6.h"unsigned int note;//音符标志(全局变量)void GPIO_INIT(void);//io口初始化void delay (unsigned int time);//延时函数void TIM1_INIT(unsigned int music);//TIM1初始化void TIM1_OC(void);//TIM1输出比较初始化int main( void ){GPIO_INIT();//io口初始化PD_ODR=0xfc;//pd0 pd1输入全0的扫描码111111100b=0fcHdelay(5);//延迟一下,让引脚输入信号稳定EXTI_CR1|=0X08;//0000 10000将EXTI_CR1的位3置1EXTI_CR1&=0Xfb;//1111 1011将EXTI_CR1的位2置0,即设置pb口的中断触发方式为仅下降沿触发TIM1_OC();//TIM1输出比较初始化TIM1_CCER1|=0x01;//TIM1比较输出使能输出asm("rim");//开中断}/**********延时子程序***************/void delay(unsigned int time){while(time--);}/*******键盘矩阵的io口初始化*********/void GPIO_INIT(void){PB_DDR=0X00;PB_CR1=0X0F;PB_CR2=0X0F;//PB的pb0到pb3口为矩阵键盘的输入口,带上拉,允许外中断输入PD_DDR=0X03;//PG的pg0跟pg1口为输出口PD_CR1=0X00;//OD输出PD_CR2=0X00;//低速}/*****************键盘中断扫描方式程序**********************/#pragma vector=6//查表,键盘pb口的中断为4,加上前面两个不可屏蔽的中断则序号为6 __interrupt void SCAN_KEY(){unsigned char scan;if((PB_IDR|0XF0)!=0xff)//当有按键按下的时候,pb口有一个不是高电平时候,证明有至少一个按键被按下{delay(5);//延时,避免脉冲抖、动产生的误差if((PB_IDR|0XF0)!=0xff);//确定是有按键按下,进行扫描判断{PD_ODR_ODR1=1;//pd0 pd1输入全0的扫描码1111 1110b=0fEHPD_ODR_ODR0=0;if((PB_IDR|0XF0)!=0xff){if((PB_IDR|0XF0)!=0xff)note=1,scan=0xfe;else if(PB_IDR_IDR1==0)note=3,scan=0xfd;else if(PB_IDR_IDR2==0)note=5,scan=0xfb;else if(PB_IDR_IDR3==0)note=7,scan=0xf7;}PD_ODR_ODR1=0;//pd0 pd1输入全0的扫描码1111 1101b=0fdHPD_ODR_ODR0=1;if((PB_IDR|0XF0)!=0xff){if(PB_IDR_IDR0==0)note=2,scan=0xfe;else if(PB_IDR_IDR1==0)note=4,scan=0xfd;else if(PB_IDR_IDR2==0)note=6,scan=0xfb;else if(PB_IDR_IDR3==0)note=8,scan=0xf7;}PD_ODR=0xfc;//恢复pd口低电平扫描功能,不影响下次的中断产生TIM1_INIT(note);while((PB_IDR|0XF0)!=0xff) // while(PB_IDR==scan){TIM1_CR1|=0X01;//TIM1定时器使能}TIM1_CR1&=0Xfe;//TIM1定时器禁止}}}/*********************TIM1初始化****************/void TIM1_INIT(unsigned int music){unsigned int pscr;//TIM1_PSCR的数值unsigned int arr;//TIM1_ARR的数值switch(music){case 1:pscr=43,arr=44;break;//对应的DO的设置case 2:pscr=40,arr=41;break;//对应的RE的设置case 3:pscr=38,arr=39;break;//对应的MI的设置case 4:pscr=37,arr=38;break;//对应的FA的设置case 5:pscr=35,arr=36;break;//对应的SO的设置case 6:pscr=33,arr=34;break;//对应的LA的设置case 7:pscr=31,arr=32;break;//对应的SI的设置case 8:pscr=30,arr=31;break;//对应的DO'的设置}TIM1_PSCRH=0;//数字小于256,高八位都为0TIM1_PSCRL=(unsigned char)pscr;TIM1_ARRH=0;//数字小于256,高八位都为0TIM1_ARRL=(unsigned char)arr;TIM1_CR1=0X04;//TIM1_CR1=0000 0100B,边沿对齐模式,向上计数,但是计数器还没使能TIM1_CNTRH=0;TIM1_CNTRL=0;//使一开始的方波完整}/**************TIM1输出比较初始化***************/void TIM1_OC(void){PC_DDR|=0X02;PC_CR1|=0X02;PC_CR2=0X00;//初始化TIM1_CH1的引脚PC1为输出方式,由后级电路决定选择推挽输出TIM1_CCR1H=0X00;TIM1_CCR1L=0X16;//初始化TIM1_CCR输出比较寄存器,由于选择011模式,所以CCR1的值可以是随意TIM1_CCMR1=0X38;//初始化TIM1_CCMR1的CC1S为00;以及OC1M[2:0]位为011,而且实用预装载功能TIM1_BKR=0X80;//初始化刹车寄存器TIM1_CCER1&=0xfd;//高电平有效,但是还没有使能pwm输出}。

STM8S操作DHT11温湿度传感器c语言程序模组

STM8S操作DHT11温湿度传感器c语言程序模组

STM8S操作DHT11温湿度传感器c语言程序模组STM8S @ 16M 定时器定时5ms中断一次#define _G_DHT11#include "dht11.h"unsigned char uc_DHT11Value[SIZE];//全局变量得到的温湿度值unsigned int ui_TempValue = 0;unsigned int ui_HumiValue = 0;extern unsigned char uc_20mstimeflag;/************************************************************* 函数名称:函数功能:入口参数:入口参数的类型和含义:出口参数:备注:*************************************************************/ unsigned char s_ComDHT11(void){unsigned char i,temp,comdata;for(i = 8;i>0;i--){while(!DHT11_DATA_VALUE);DHT11_Delay_10us();DHT11_Delay_10us();DHT11_Delay_10us();DHT11_Delay_10us();temp = 0;if(DHT11_DATA_VALUE){temp =1;}comdata = comdata << 1;comdata = comdata|temp;while(DHT11_DATA_VALUE);}return comdata;}函数名称:函数功能:入口参数:入口参数的类型和含义:出口参数:备注:*************************************************************/ void g_ReadTempAndHumi(void){DHT11_DATA_OUT;DHT11_DATA_LOW;//layTime(40);// 至少18MS的延时,在中断计时里实现uc_20mstimeflag = 1;while(uc_20mstimeflag);DHT11_DATA_HIGH;DHT11_DATA_IN;DHT11_Delay_10us();DHT11_Delay_10us();DHT11_Delay_10us();while(!DHT11_DATA_VALUE); //80us的应答信号DHT11 TO MCU while(DHT11_DATA_VALUE); //80us的通知信号DHT11 TOMCUuc_DHT11Value[0] = s_ComDHT11();uc_DHT11Value[1] = s_ComDHT11();uc_DHT11Value[2] = s_ComDHT11();uc_DHT11Value[3] = s_ComDHT11();uc_DHT11Value[4] = s_ComDHT11();if((uc_DHT11Value[0] + uc_DHT11Value[1] + uc_DHT11Value[2] + uc_DHT11Value[3]) == uc_DHT11Value[4]) {ui_HumiValue = uc_DHT11Value[0];ui_TempValue = uc_DHT11Value[2];}}函数名称:函数功能:入口参数:入口参数的类型和含义:出口参数:备注:*************************************************************/ void DHT11_Delay_10us(void){for(unsigned char uc_10us = 0;uc_10us < 34;uc_10us ++);}头文件部分#ifndef __DHT11_H#define __DHT11_H#include "iostm8s105c6.h"#ifdef __cplusplusextern "C" {#endif#ifndef _G_DHT11#define DHT11_extern extern#else#define DHT11_extern#endif/**************宏定义****************///#define DATA_DR PA_ODR_ODR6 //OUTPUT//#define DATA_SR PA_IDR_IDR6 //IN STATE#define DHT11_DATA_OUT PE_DDR_DDR3 = 1 //输出#define DHT11_DATA_IN PE_DDR_DDR3 = 0 //输入#define DHT11_DATA_HIGH PE_ODR_ODR3 = 1 //拉高#define DHT11_DATA_LOW PE_ODR_ODR3 = 0 //拉低#define DHT11_DATA_PULL_UP PE_CR1_C13 = 1 //上拉#define DHT11_DATA_FLOATING PE_CR1_C13 = 0 //浮空#define DHT11_DATA_PUSH_PULL PE_CR1_C13 = 1 //推挽#define DHT11_DATA_OPEN_DRAIN PE_CR1_C13 = 0 //开漏#define DHT11_DATA_VALUE PE_IDR_IDR3 //DQ值#define SIZE 5/**************接口函数***************/unsigned char s_ComDHT11(void);DHT11_extern void g_ReadTempAndHumi(void); void DHT11_Delay_10us(void);#ifdef __cplusplus}#endif#endif。

stm8s乘法

stm8s乘法

STM8S 是 STMicroelectronics 公司的一个微控制器系列。

在STM8S 微控制器中,你可以使用内建的硬件乘法器进行乘法运算。

以下是一个简单的例子,演示如何在 STM8S 中进行乘法运算:
```c
#include "stm8s.h"
void main(void)
{
// 初始化系统时钟
CLK_CKDIVR = 0;
// 初始化两个需要相乘的数
uint16_t a = 10;
uint16_t b = 2;
// 使用硬件乘法器进行乘法运算
uint32_t result = a * b;
// 输出结果
while (1)
{
// 这里只是简单地通过串口输出结果,你可以根据需要修改这部分代码
USART_SendData(USART1, (uint8_t)(result >> 8)); USART_SendData(USART1, (uint8_t)(result &
0xFF));
delay_ms(1000);
}
}
```
这段代码首先初始化了系统时钟,然后定义了两个需要相乘的数 `a` 和 `b`。

然后,它使用硬件乘法器进行乘法运算,并将结果存储在 `result` 变量中。

最后,它通过串口不断地输出结果。

请注意,你需要根据你的硬件和开发环境来配置和使用串口。

如果你使用的是其他版本的 STM8S 或者使用的是其他编译器,代码可能需要进行一些修改才能正常工作。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实例一:控制灯的亮灭(或者蜂鸣器响,只要连接相应端口就可以了):#include "stm8s.h"//头文件#define ulong unsigned long/////////////////////////////////////////////////////////////////////////////// void delay(ulong i){ulong j;for(j=0;j<i;j++){;}}////////////延时函数void main(void)////////////主函数{GPIO_DeInit(GPIOD);GPIO_Init(GPIOD, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);while(1){GPIO_WriteHigh(GPIOD, GPIO_PIN_1);delay(10000);delay(10000);delay(10000);GPIO_WriteLow(GPIOD, GPIO_PIN_1);delay(10000);delay(10000);delay(10000);}}第二步:控制灯按照一定的频率闪烁:频率可以使用时钟!Stm8启动时,主时钟默认为HSIRC时钟的8分频,HSIRC是可以提供一个低成本的16MHz 时钟源,#include "stm8s.h"//头文件void CLK_Configuration(void);void main(void)////////////主函数{GPIO_DeInit(GPIOD);GPIO_Init(GPIOD, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);CLK_Configuration();while(1){GPIO_WriteReverse(GPIOD, GPIO_PIN_1);}}void CLK_Configuration(void){/* Fmaster = 16MHz */CLK_HSIPrescalerConfig( CLK_PRESCALER_HISDIV1);}例题三:灯闪亮的同时蜂鸣器响#include "stm8s.h"//头文件#define ulong unsigned long/////////////////////////////////////////////////////////////////////////////// void delay(ulong i){ulong j;for(j=0;j<i;j++){;}}////////////延时函数);void main(void)////////////主函数{GPIO_DeInit(GPIOD);GPIO_DeInit(GPIOB);GPIO_Init(GPIOD, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);GPIO_Init(GPIOB, GPIO_PIN_0,GPIO_MODE_OUT_PP_LOW_FAST );while(1){GPIO_WriteHigh(GPIOD, GPIO_PIN_1);delay(10000);delay(10000);GPIO_WriteLow(GPIOD, GPIO_PIN_1);delay(10000);delay(10000);GPIO_WriteHigh(GPIOB, GPIO_PIN_0);delay(10000);delay(10000);GPIO_WriteLow(GPIOB, GPIO_PIN_0);delay(10000);delay(10000);}}时钟控制器功能强大而且灵活易用。

其目的在于使用用户在获得最好性能的同时,亦能保证消耗的功率最低。

用户可以独立管理各个时钟源,并将它们分配到CPU或者各个外设。

主时钟和CPU的时钟均带有分频器。

主时钟源:四种时钟源可以作为主时钟源:1.1—24MHz高速外部晶体振荡器(HSE)2.最大24MHz高速外部时钟信号(HSE user-ext)3.16MHz高速内部RC振荡器(HSI)4.128KHz低速内部RC(LSI)各个时钟源可独立打开或者关闭,从而优化功耗。

HSE:高速外部时钟信号,由两个时钟源产生:HSE外部晶体/陶瓷谐振器;HSE用户外部有源时钟。

(为了最大限度的减少输出失真和减少启动失真的稳定时间,谐振器和负载电容应尽可能的靠近谐振器引脚。

负载电容值应根据所选的谐振器进行调整。

)外部1至24MHz的振荡器其优点在于能够产生精确的占空比为50%的主时钟信号。

为使系统快速启动,复位后时钟控制器自动使用HSI的8分频(HSI/8)做为主时钟。

其原因为HSI的稳定时间短,而8分频可保证系统在较差的V DD条件下安全启动。

时钟设置的目的到底是什么?时钟设置肯定会出现中断?貌似是这样的:运用合适的时钟配置可以使得功耗降低,有时候计数频率很大,需要很大的计数或者怎么样时,需要使用其他的时钟,即非默认的时钟!暂且这样解释!例题四:利用中断按键控制灯的亮灭。

#include "stm8s.h"//头文件void main(void)////////////主函数{GPIO_DeInit(GPIOD);GPIO_DeInit(GPIOB);GPIO_Init(GPIOD, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_IN_FL_IT);EXTI_DeInit();EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB ,EXTI_SENSITIVITY_FALL_ONLY );///////定义端口的外部中断enableInterrupts();//////////////////这个一定不能丢,中断使能while(1){}}#pragma vector=6//中断编号+2__interrupt void EXIT_PORTB_IRQHander(void){if((GPIO_ReadInputData(GPIOB)&GPIO_PIN_0)==0x00)/////检查是否按下{GPIO_WriteReverse(GPIOD,GPIO_PIN_1);}}//////默认的时钟为HSI的8分频,即上电默认的频率。

中断设置为上升沿触发:则程序会有微小的变化:#include "stm8s.h"//头文件void main(void)////////////主函数{GPIO_DeInit(GPIOD);GPIO_DeInit(GPIOB);GPIO_Init(GPIOD, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);GPIO_Init(GPIOB, GPIO_PIN_0, GPIO_MODE_IN_FL_IT);EXTI_DeInit();EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOB ,EXTI_SENSITIVITY_RISE_ONLY );///////定义端口的外部中断enableInterrupts();//////////////////这个一定不能丢,中断使能while(1){}}#pragma vector=6//中断编号+2__interrupt void EXIT_PORTB_IRQHander(void){if((GPIO_ReadInputData(GPIOB)&GPIO_PIN_0)==0x01)/////检查是否按下{GPIO_WriteReverse(GPIOD,GPIO_PIN_1);}}时钟这里到底是怎么回事啊?LSI等如何配置,配置时钟做什么用的?例题五:设计一个程序使得当按键按下后发光二极管按照不同的频率闪烁。

分析:不同的频率闪烁,可以设置为按照100,500,1000,2000Hz的频率闪烁。

定时器timer4的使用:该定时器由一个带可编程预分频器的8位可位自动重载的向上计数器所组成,它可以用来做时基发生器,具有溢出中断功能。

Timer6同时钟/触发信号控制器一起用于定时器同步和级联。

Time4的主要功能包括:1.8位向上计数的自动重载计数器(既然是向上计数,那么计算初值时?)2.3位可编程的与分配器(可在运行中修改),提供1,2,4,8,16,32,64,和128这8种分频比例。

3.中断产生——在计数器更新时:计数器溢出。

Timer6的主要功能:1.8位向上计数的自动重载计数器2.3位可编程的与分配器(可在运行中修改),提供1,2,4,8,16,32,64,和128这8种分频比例。

3.用于和外部信号相连和定时器级联的同步电路4.中断产生:——在计数器更新时:计数器溢出——在触发信号输入时。

Timer4和timer6中断:该定时器的时钟源是内部时钟(Fmaster)。

该时钟源是直接连接到CK_PSC时钟的,CK_PSC 时钟通过预分频器分频后给定时器提供CK_CNT时钟。

预分频器功能如下:1.预分频器是基于由一个3位寄存器(在TIMX_PSCR寄存器中)来控制的一个7位的计数器。

由于该控制寄存器是带缓冲的所以它可以在系统运行中被改变。

可以分频计速器的时钟频率为1到128之间的2的任意次幂。

预分频器的值是通过一个预装载寄存器来载入的。

一旦LS字节被写入时,保存当前要被使用值影子寄存器的值就被立即载入。

对TIMX_PSCR寄存器的读操作是访问预装载寄存器,因此在读的过程中没有什么特别要注意的地方。

中断使能寄存器:TIMx_IER位7:保留,须保持清零位6:TIE:触发中断使能:0:触发中断禁止;1:触发中断使能;位5:1 保留,须保持清零位0:UIE:更新中断使能:0:更新中断禁止;1:更新中断使能状态寄存器1(TIMX_SR1)位7:保留,须保持清零位6:TIF:触发中断标志位(此位在触发事件发生时(检测到TRGI信号的有效沿,在选择门控模式时硬件置位。

可以由软件清零。

)0:无触发事件产生;1:触发事件发生,此位当寄存器更新时由硬件置位(在timer4中该位保留)位5:1 保留,须保持清零位0:UIF:更新中断标志(此位在更新事件发生时由硬件置位。

可以由软件清零)0:无更新事件产生;1:跟新事件发生。

此位当寄存器更新时由硬件置位。

1.如果TIM4_CR1中的UDIS=0,则发生在计数器溢出时。

相关文档
最新文档