谁用IAR给 stm8s003 iarF3 单片机用C语言写个程序 用一个按键控制一个LED

&&/&&&&/&&&&/&&
忙活了半天,准备工作做了那么多,终于要编写我们的程序代码了。如果学过 C 语言的话,你应该很轻松的跟着我的编程自己写出来,如果没学过 C 语言也没关系,你先照着我的抄,我会在合适的位置写出来对 C 语言语法的解释,这样抄几次后再看看解释,就应该很明白了,抄的时候一定要认真,尤其标点符号不可以搞错。
第一个单片机程序:
#include &reg52.h&
//包含特殊功能寄存器定义的头文件
sbit LED = P0^0;
//位地址声明,注意:sbit 必须小写、P 大写!
void main(){
//任何一个 C 程序都必须有且仅有一个 main 函数
//分号表示一条语句结束
先从程序语法上来分析一下:
main 是主函数的函数名字,每一个 C 程序都必须有且仅有一个 main 函数。
void 是函数的返回值类型,本程序没有返回值,用 void 表示。
{}在这里是函数开始和结束的标志,不可省略。
每条 C 语言语句以;结束的。
逻辑上来看,程序这样写就可以了,但是在实际单片机应用中,存在一个问题。比如我们的程序空间可以容纳 100 行代码,但是我们实际上的程序只用了 50 行代码,当运行完了50 行,再继续运行时,第 51 行的程序不是我们想运行的程序,而是不确定的未知内容,一旦执行下去程序就会出错从而可能导致单片机自动复位,所以我们通常在程序中加入一个死循环,让程序停留在我们希望的这个状态下,不要乱运行,有以下两种写法可以参考:
参考程序一:
#include &reg52.h&
sbit LED = P0^0;
void main(){
参考程序二:
#include &reg52.h&
sbit LED = P0^0;
void main(){
程序一的功能是程序在反复不断的无限次执行 LED = 0;这条语句,而程序二的功能是执行一次,然后程序直接停留下来等待,相对程序一来说程序二更加简洁一些。针对于图 2-6,我们这个程序能够把小灯点亮,但是这个程序却点不亮我们板子上的小灯,这是为什么呢?
这里大家就要培养一个意识了,我们做单片机编程,实际上算是硬件底层驱动程序开发,这种程序的开发,是离不开电路图的,必须根据我们的电路图来进行程序的编写。如果我们设计电路板的电路图和图 2-6 一样的话,程序可以成功点亮小灯,但是如果不一样,就可能点不亮。
我们的开发板上,还有一个 74HC138 作为 8 个 LED 小灯的总开关,而 P0.0 仅仅是个分开关。如同我们家里总是有一个供电总闸,然后每个电灯又有一个专门的开关,我们刚才的程序仅仅打开了那个电灯的开关,但是没有打开那个总电闸,所以程序需要加上这部分代码。
因为这节课要介绍的内容比较多,所以我们把 74HC138 的原理以及为什么要加额外的代码在下节课统一介绍,这节课我们直接加上这部分代码,大家知道有这么一回事就可以了。
#include &reg52.h&
//包含特殊功能寄存器定义的头文件
sbit LED = P0^0;
//位地址声明,注意:sbit 必须小写、P 大写!
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
void main(){
ENLED = 0;
ADDR3 = 1;
ADDR2 = 1;
ADDR1 = 1;
ADDR0 = 0;
//点亮小灯
while (1);
//程序停止在这里
写了这么多碌挠锞洌湛即蠹铱赡芫醯煤苈榉常裁从械氖樯铣绦蚝芗虻ゾ涂梢缘懔列〉疲颐钦饫锶凑饷绰榉衬亍4蠹乙私庖坏悖褪俏颐亲稣飧鲅鞍澹淙唤鼋鎏峁└蠹壹虻パ笆褂茫俏颐且驳冒凑帐导什返目⒛J饺ド杓疲宰酆峡悸且蛩睾芏啵蠹已У胶蟊呔突崦靼姿纳杓萍壑盗耍饫锎蠹抑灰盼颐侨プ鼍涂梢粤恕
程序编好了,我们要对我们的程序进行编译,生成我们需要的可以下载到单片机里的文件,在编译之前,我们先要勾选一个选项,Project--&Options for Target &Target1‟...,或者直接点图 2-17 中红框内的快捷图标:
图 2-17& 工程选项图标
在弹出的对话框中,点击 Output 选项页,勾选其中的&Create HEX File&复选框,然后点 OK,如图 2-18 所示。
图 2-18& 创建 HEX 文件
设置好以后呢,点击&Project--&rebuild all target files&,或者鼠标点击图 2-19 中红框内的快捷图标,就可以对程序进行编译了。
图2-19& 编译程序
编译完成后,在我们的 Keil 下方的 Output 窗口会出现相应的提示,大家注意看图 2-20,这个窗口告诉我们编译完成后的情况,data=9.0,指的是我们的程序使用了单片机内部的 256字节 RAM 资源中的 9 个字节,code=29 的意思是使用了 8K 代码 Flash 资源中的 29 个字节。
当提示&0 Error(s), 0 warning(s)&表示我们的程序没有错误和警告,就会出现&creating hex file&from &LED&...,意思是从当前工程生成了一个 HEX 文件,我们要下载到单片机上的就是这个HEX 文件。如果出现有错误和警告提示的话,就是 Error 和 warning 不是 0,那么我们就要对程序进行检查,找出问题,解决好了再进行编译产生 HEX 才可以。
图2-20& 编译输出信息
到此为止,程序就编译好了,下边我们就要把编译好的程序文件下载到单片机里了。STM8S003F3
不管什么单片机,想要控制LED灯,只能是通过控制单片机芯片的I/O引脚电平的高低来实现。
同样在ST单片机上,I/O引脚可以被软件设置成各种不同的功能,如输入或输出,所以被称为 GPIO (General-purpose I/O)。
而GPIO引脚又被分为GPIOA、GPIOB,,,,GPIOG不同的组,每组端口分为 0~15,共16个不同的引脚不等,
对于不同型号的芯片,端口的组和引脚的数量不尽相同,具体请参考相应ST单片机芯片型号的datasheet。&
根据ST单片机的GPIO特点,控制LED灯的步骤如下:&
1.在众多 GPIO端口引脚中选定需要控制的特定引脚[与LED相连的控制引脚]&
2.根据外设配置GPIO需要的特定功能&
3.通过设置 GPIO输出电压的高低控制LED的亮和灭
STM8S003F3是一款比较小巧的单片机,在IO资源需求够小的时候可以选择,同时它的控制也相对的简单些,
STM8系列的单片机一般都是使用IAR for STM8的开发环境,同时注意,在安装时最好把STLink下载器直接插在电脑上安装,
因为在安装IAR for STM8开发环境时会自动安装STLink的驱动。[根据本人经验,插上下载器安装最容易安装成功]
二、硬件电路图
三、需要用到的函数库
stm8s_gpio.c
/*********************************************************
*平台:IAR for STM8 V2.10.4
*主控:STM8S003F3
**********************************************************/
#include &stm8s.h&
#include &led.h&
#include &delay.h&
int main(void)
LED_Init();
//LED初始化
//延时初始化
LED_Not(0);
Delay_ms(500);
#include &led.h&
void LED_Init(void)
//定义LED的管脚的模式 推挽-输出高电平-低速
//GPIO_MODE_OUT_PP_LOW_SLOW
//本来可以写成一句
GPIO_Init(GPIOC,GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6,GPIO_MODE_OUT_PP_HIGH_SLOW);
//但是IAR的软件这样写会出警告,所以只能分开写
GPIO_Init(GPIOC,GPIO_PIN_3,GPIO_MODE_OUT_PP_HIGH_SLOW);
GPIO_Init(GPIOC,GPIO_PIN_HNIB,GPIO_MODE_OUT_PP_HIGH_SLOW);
//LED控制引脚取反
void LED_Not(int n)
case 0: GPIO_WriteReverse(GPIOC, GPIO_PIN_3);
case 1: GPIO_WriteReverse(GPIOC, GPIO_PIN_4);
case 2: GPIO_WriteReverse(GPIOC, GPIO_PIN_5);
case 3: GPIO_WriteReverse(GPIOC, GPIO_PIN_6);
编译下载后就能看到LED一闪一闪的
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4987次
排名:千里之外
原创:26篇
转载:30篇
(2)(1)(9)(44)最近在使用STM8S003F模拟串口发送数据,网上资源很多,但是没有找到我需要的,因此自己写一篇文章,做一个总结,这篇文章主要是不用库函数实现发送简单的过程。
1、串口通信原理和模拟串口发送数据的原理
标准串口数据格式为:起始位(1bit)+数据位(8bit)+校验位(1bit)+停止位(1bit)。其中起始位为低电平,停止位为高电平。
串口通讯需要设置波特率和检查COM口。
思路是这样的,我们使用定时器TIM2来定时,每隔一端时间发送一个位,从而实现模拟串口发送数据。
2、获得定时器ARR自动装载的值
为了简便,我们不要校验位,因此共有10个位的数据。
我以stm8中9600bit/s的波特率计算的过程为例(1秒钟传输9600位)。
可以计算出传输1位所需要的时间 T1 = 1/9600 约为104us。
stm8 内部晶振频率为16M,我采用16分频也就是1M,故MCU震荡周期为 1/1M = 1us。
由上面的计算我们可以知道要发送一位数据,定时器中定时的自动装载的&#20540;应设为为 104/1 =<span style="color:#ff。
3、实现过程
在实现过程中,我们在工程文件夹SimUART中共分了4个文件夹(分别为System:存放系统文件;Project:存放项目文件;User:存放main.c和UserApp.c;My_Lib:存放其它常用的文件)。根据我们将用到的单片机的资源,我们在My_Lib中分了三个文件,分别是——Delay:存放与延时函数相关的文件;IO:存放与IO口相关函数的文件;Time:与定时器相关函数的文件。下面我贴出相关函数的.c文件,而.h文件省略不写,有需要的同学可以根据文章后面的网址下载使用。我的编程环境是IAR,需要自己建立IAR工程。MARK,以后介绍。下面详细介绍(Project和System省略不写,其中System只用了stm8s.h)。
3.1、一切从main.c开始
首先,在main.c中我们需要对用到的单片机的资源进行初始化。我们将其写在All_Config()【在UserApp.c中】函数内,代码如下:
//head file
#include &UserApp.h&
#include &IO.h&
#include &User.h&
#include &Time.h&
//初始化函数
void All_Config( void )
Clock_Config();
IO_Init();
TIM2_Init();
其中User.h是我将自己常用的宏写在了一个文件里面,对应于main.c。
在没有接外部时钟的时候,STM8S003F在启动时主时钟默认为HSI RC时钟的8分频,我们这里的初始化仅指定为16MHZ高速内部RC振荡器(HSI),也可以省略不写,Clock_Config()【在UserApp.c中】函数代码如下:
//初始化时钟 选择内部16M晶振
void Clock_Config()
CLK-&CKDIVR &= ~( BIT(4) | BIT(3) );
我选择单片机的PD2作为我的模拟串口的数据发送口,IO_Init()【在IO.c中】函数代码如下:
//head file
#include &IO.h&
#include &User.h&
void IO_Init()
//TXD:TXD位推挽输出
UART_PORT-&ODR |= UART_PIN_TX; //
UART_PORT-&DDR |= UART_PIN_TX; //
UART_PORT-&CR1 |= UART_PIN_TX; //
UART_PORT-&ODR &= ~UART_PIN_TX;
UART_PORT-&ODR |= UART_PIN_TX;
其中在IO.h中的宏定义为:
#define UART_PORT GPIOD
#define UART_PIN_TX 0X04 //
#define UART_PIN_RX 0X08 //
下面是定时器的初始化,在使用定时器的时候我们分为以下几步:
a、选择定时器,我们选择TIM2;
b、定时器的时钟分频(注意要看是使用的默认8分频还是有更改),我开始没有分频,需要16分频;
c、填充定时器自动装载的&#20540;,我这里是<span style="color:#ff;
d、开启定时器;
注意计数器CNTR上电自动为0,我们还是清零一下,使用的自动装载寄存器后,自动重装载寄存器决定了定时器的上溢时机,当定时器的计数器中数&#20540;达到了自动重装载寄存器规定的&#20540;,计数器就要归零。也就是说自动重装载寄存器决定了定时器的周期。
在这篇文章介绍的模拟串口发送数据的方法中并没有使用中断。TIM2_Init()【在TIM2.c中】函数代码如下:
//head file
#include &TIM2.h&
#include &User.h&
void TIM2_Init()
CLK-&PCKENR1 |= CLK_PCKENR1_TIM2;
//TIM2 enable
TIM2-&PSCR
//16分频 1MHZ 1us
TIM2-&ARRH
= 104 && 8;
//自动装载 每52us复位一次TIM2
TIM2-&ARRL
//每1us递减1
&pre name=&code& class=&cpp&&
TIM2-&CNTRH = 0;
TIM2-&CNTRL = 0;
TIM2-&CR1 |= TIM2_CR1_CEN; //开启定时器}
完成初始化以后,我们应该写发送程序,为了简单的发送,我们选择发送0x55,因为它在示波器中显示方波。我们在UserApp.c中写我们的实现我们的模拟串口的发送。
发送数据的规则是:
a、共10位数据(因此需要16为的数据,8位是不行的),由于我们发送的数据是8位,所以有一个转换的过程;
b、先发低位,再发高位;
c、在发送函数中有时间延时代码,保证没法每一次数据都是一个计数时间(即完成一次104计数)
发送函数SimUART_TxByte()【在UserApp.c中】代码如下
void SimUART_TxByte( u8 SendData )
static u16 Send_All = 0;
Send_All = SendD
Send_All = ( Send_All && 1 ) | 0X0200;
//需要发送的10个位的数据
TIM2-&CNTRH = 0;
TIM2-&CNTRL = 0;
TIM2-&SR1 &= ~TIM2_SR1_UIF;
//先发低位,再发高位
for( BitNum = 0;
BitNum&10 ;
BitNum++ )
if( Send_All & 0X0001 )
//如果是高电平,发高电平
UART_PORT-&ODR |= UART_PIN_TX;
//如果是低电平,发低电平
UART_PORT-&ODR &= ~UART_PIN_TX;
Send_All &&= 1;
//右移一位
//等待波特率时间
while( (TIM2-&SR1 & TIM2_SR1_UIF) == 0 );
TIM2-&SR1 &= ~TIM2_SR1_UIF;
其中UART_PIN_TX为IO.c中的宏定义。
3.2、补全main()函数
完成上面的代码之后我们可以测试一下,下面我们完成main()函数,代码如下:
//head file
#include &User.h&
#include &UserApp.h&
#include &Delay.h&
int main( void )
char Test = 0;
//char Test = 0x55;
//测试数据
All_Config();
//发送循环
SimUART_TxByte( Test++ );
Delay_50000();
//延时,防止数据过多
//return 0;
在0x55发送正确之后,我们发送0x00到0xFF,若波特率不正确将会出现发送不连贯的现象。为了防止数据过多,我们需要一个延迟函数,Delay_50000()【IO.C中】函数代码如下:
//Head file
#include &Delay.h&
void Delay_50000()
for( a=0 ; a&100 ; a++ )
for( b=0 ; b&500 ; b++ );
至此我们使用IO口模拟串口(未使用库函数)发送数据的功能已经实现,相关代码可以移步下面的地址下载使用,欢迎大家和我一起学习和交流。
源代码下载地址:
/***************************************************************************************************************************************************************************************/
2、修改时间:
作者:Alan
说明:1、修正错误:串口数据中,起始位为低电平,停止位为高电平(之前错误的以为停止位为低电平)。
& & & & & & 2、调整文章&#26684;式。
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
1、修改时间:
作者:Alan
说明:完成文章。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5949次
排名:千里之外
原创:35篇
(1)(1)(1)(11)(10)(12)(5)(2)(1)(3)

我要回帖

更多关于 stm8s003f3 的文章

 

随机推荐