之前说不想写单片机实验的这一部分的,可是想想不写不行,要不以后说不清楚,因为学习中会遇到一些修改协议栈的IO的东西,比如LED灯啊,串口的IO设置啊等等,如果不做这部分的实验,可能后面看不明白,其实也是很简单的单片机实验而已,我这个只学过几天科班的单片机的能够搞明白,相信你们不用看都明白。
我手头上拿得是佳杰的实验开发板,之前是因为公司的板子太久没有回来,我又不想等,所以就去淘宝买了这套板子,我叫他帮我加了一块,所以我有三块板子,全带lcd,还比较便宜,连带邮费360左右,芯片是cc2530F256的,就是说flash是256K的,这个在单片机领域来说算是很大的flash了,RAM没得选的,就8K。
板子拿到的第一天觉得特别兴奋,因为之前只玩过嵌入式linux开发,后来在公司玩了一下cc1110和cc1101的东西,本来是想做一个无线协议栈的(肯定没有zigbee这种技术那么强大,能用,可是还有很多东西要考虑,后来就搁置了),现在玩zigbee,还挺新鲜的,我本来不是做学单片机出身的,所以对这些裸机编程没大家那么熟悉,而且新接触cc2530,说得肯定错漏百出,欢迎拍砖。高手们,就没必要看了,刚入门的,也许有点帮助。
对于zigbee的介绍什么的我就不废话了,我们直接在板子上实现我们的一个led流水灯程序。
用IAR建立一个工程,然后进行配置
首先选择我们的cpu,我们是cc2530
然后配置一些堆栈
设置一下config
好了,工程设置好了之后,我们新建一个.c文件,然后把他add进来
代码很少,想想我以前在linux下写一个led驱动的时候要做的事情那比这个多得去了
#include <ioCC2530.h> #define LED1_NUM 0x00 #define LED2_NUM 0x01 #define LED3_NUM 0x02 #define LED_ON_MODE 0x00 #define LED_OFF_MODE 0x01 #define LED1 P1_0 #define LED2 P1_1 #define LED3 P1_4 static void setLedMode(unsigned char lednum,unsigned char mode) { switch(lednum) { case LED1_NUM: LED1 = !!mode; break; case LED2_NUM: LED2 = !!mode; break; case LED3_NUM: LED3 = !!mode; break; default: break; } } static void initLED(void) { P1SEL &= ~0x13; P1DIR |=0x13; LED1 = !!LED_OFF_MODE; LED2 = !!LED_OFF_MODE; LED3 = !!LED_OFF_MODE; } static void Delay(unsigned char n) { unsigned char i; unsigned int j; for(i = 0; i < n; i++) for(j = 1; j; j++) ; } int main() { unsigned char status = 1; initLED(); while(1){ setLedMode(LED1_NUM,status) ; Delay(5); setLedMode(LED2_NUM,status) ; Delay(5); setLedMode(LED3_NUM,status) ; Delay(5); status = !status; } }
我们来看看佳杰的LED是怎么接的:
其实这个x接的是p1_0.其他两盏灯分别接在了P1_1和p1_4上,好了,下面对刚学单片机的解析一下这个程序
首先是初始化LED的函数
static void initLED(void){ P1SEL &= ~0x13; P1DIR |=0x13; LED1 = !!LED_OFF_MODE; LED2 = !!LED_OFF_MODE; LED3 = !!LED_OFF_MODE; }
首先我们要用这个三个io口作为我们的led灯控制接口,那么我们必须得去初始化这个几个口,要不使用起来就会有问题,那初始化该做什么事情呢?首先我们要把这三个口设置为普通的io口,因为我们的LED就好是一个普通的设备,然后我们要设置这三个io的输入输出方向,因为我们的led是一个输出设备,那么我们要把这三个口设置i为输出。
好,怎么设置为普通的IO口呢?首先我们来看一下P1SEL这个寄存器,涉及到寄存器的东西,不懂的话,就去找datasheet,打开datasheet然后ctrl+f,然后输入P1SEL然后回车查找,我们可以找到这么一段:
The registers for the I/O ports are described in this section. The registers are:
· P0: Port 0
· P1: Port 1
· P2: Port 2
· PERCFG: Peripheral-control register
· APCFG: Analog peripheral I/O configuration
· P0SEL: Port 0 function-select register
· P1SEL: Port 1 function-select register
那么就是说这个寄存器是作为p1这组io的功能选择寄存器,然后我们在继续往下找,找找这寄存器的table
这里面说明了这寄存器每一个bit代表什么意思,是否可读可写,默认的值是什么,每一位设置为0或者1代表什么意思。我们可以看到设置为0的时候就代表这个io口是作为普通io使用的。那么我们要把p1.0,p1.1,p1.4设置为0,那么我们设置者三个bit为0,可不能影响其他bit,那么在c语言学习的时候只能用什么呢?对就是&,你把你要设置那一个bir设置为0,其他bit设置为1,然后跟原来的&就可以了,P1SEL &= ~0x13;就是做这么一件事情。
好了,配置好io为普通io之后,我们就要设置一下这个io的方向了,同样是有一个寄存器设置的:P1DIR。
好,我们继续datasheet,同样你可以找到这么一句
P1DIR: Port 1 direction register
证明我没有骗你,然后我们找找他的table
和上面那个table是一样的,我们看到,当设置对应的bit为0的时候这个io口是作为输入io口,设置为1的时候是作为输出io,那么我们肯定要把1.0,1.1,1.4这三个口设置为输出,P1DIR |=0x13;就是做这么一件事情。
好了,初始化完毕,程序也基本不用再解析了,还有要知道的是我这里的LED是低电平亮的,看原理图的接线就知道。
rebuilt all 这个工程,然后下载到板子上,拿掉仿真器,就可以看到这三盏灯依次亮起来,然后依次灭掉,如此循环。
还有个设置需要新手注意的,那就是,如果你想用在线仿真的话,那么要设置工程成这样子
如果你是像我这样子下载下去的话,那么请选择下面的other这一项,还有因为佳杰的仿真器使用到了p1.4这个口,所以必须拿掉了仿真器你才可以看到led3的亮和灭,否则你看不到这个灯有任何变化的。