[深入浅出Energia开发第一讲]51程序的移植
本帖最后由 水乐天 于 2012-9-12 17:50 编辑最近听弘毅讲LaunchPad搞活动促销,超便宜,于是俺买了10块...慢慢弄总会用到滴{:soso_e154:},这几天反复折磨有一点小小心得,不敢独享,于是打算写出来与大伙分享。
下面放出是淘宝网店地址,注意如果数量比较多的话需要有团购代码的,需要的童鞋可以去购买:
http://item.taobao.com/item.htm?id=16603403744
----------------------------------------------------------------------------------------------------------------------------
首先声明下:本文不针对零基础的朋友,如果对一般开发常识、C语言、C++完全没有了解,请绕行。
准备工作一:
俗话说工欲善其事必先利其器,首先我们来谈谈编译环境的选择:
官方的编译环境如果没有使用过请参考《Energia介绍--MSP430的Arduino IDE》或直接下载
但是官方的编译器有各种问题。。。比如中文注释不能书写。。。于是我仅用官方的编译器做调试用途,平时书写代码....还是算了吧。
我建议Windows用户选择UtralEdit IOS及Linux用户选择Sublime text 2
另外为了让我们的代码看起来更舒服 附赠代码格式化工具
----------------------------------------------------------------------------------------------------------------------------
准备工作二:
之后我们要对手头的LaunchPad做些小小的处理:
第一步 将RXD与TXD 两个跳线横过来,因为串口输出到PC需要这两个端口,否则无法进行串口输出。
第二步 将P1.6和P1.0两个LED等的跳线拔掉,因为这两个端口跟I2C端口冲突,所以在调试的时候如果你不需要这两个LED最好将其拔掉。
第三步 注意如果你的程序要使用串口的话,那么3号和4号引脚尽量不要使用,否则会影响串口数据的输出。
为了让大家更清楚地了解,如下图所示:
----------------------------------------------------------------------------------------------------------------------------
1.1 首先让我们来看一个51的程序。
本人本行是开发上位系统软件基本是硬件盲,在写这个之前完全没接触过51单片机,也没写过51的程序,各位硬件高手不要见笑哈。但是我觉得从太简单的程序入手没意思哈,于是从公司同事手中借来个台湾燃太的TN901红外温度传感器和51的范例程序。于是我们就拿这个程序开始我们的改造好了。如下图所示:
因为51的完整代码比较长还包括LCD的显示,所以我们摘主要的来看,想看完整代码点下载
主要我们需要转换的部分的包括这几个部分
一、端口定义:
sbit TN_Data = P1^0; //定义TN9接口
sbit TN_Clk= P1^2;
sbit TN_ACK= P1^4;
二、主程序部分:
/*----------------------------------主程序入口-----------------------------------*/
void main()
{
LCD_Init(); //LCD初始化
Delay5Ms();
LCD_Write_String(0, 0, Range);
LCD_Write_String(0, 1, table);
Delay400Ms();
TN_ACK = 1;
while(1)
{
TN_ACK = 0;
TN_ReadData(0x4c); //目标温度的第一个字节为0x4c
if((ReadData == 0x4c) && (ReadData == 0x0d)) //每帧的最后一个字节为0x0d
{
TN_GetData_Target();
}
DelayMs(1);
TN_ACK = 0;
TN_ReadData(0x66); //环境温度的第一个字节为0x66
if((ReadData == 0x66) && (ReadData == 0x0d)) //每帧的最后一个字节为0x0d
{
TN_GetData_Temp();
}
}
}
三、IIC接口数据传输:
void TN_ReadData(uchar flag) //读数据
{
uchar i,j,k;
bit BitState = 0; //每次发七帧
for(k=0;k<7;k++)
{
for(j=0;j<5;j++) //每帧5个字节
{
for(i=0;i<8;i++)
{
while(TN_Clk);
BitState= TN_Data;
ReadData= ReadData<<1;
ReadData= ReadData|BitState;
while(!TN_Clk);
}
}
if(ReadData==flag)k=8;
}
TN_ACK=1;
}
虽然我从没写过51的程序,但是我觉得大体上51程序结构都应该差不多,所以我按照这种方法来转换就好,这个程序搞定了基本其它程序也类似如此。
首先我们来转换,第一部分端口的定义,51这里用的类型是sbit,对应应该是byte 0或1 估计是标识每个端口的高低电平,但是我们这里与51程序的含义不同应该标识具体的端口号,所以我们这里采用int类型,如下所示:
intTN_Data=7;
int TN_Clk=8;
int TN_ACK=9;
之后我们来看程序的入口函数,注意这里的端口值改变比如 TN_ACK=1; (51代码原来很精简哦)其实是给ACK端口赋值为高电平,所以我们这里应该对应的写法是pinMode(TN_ACK, OUTPUT);//指定ACK引脚为输出脚
digitalWrite(TN_ACK,HIGH);//将指定端口输出为高电平
为了处理方便我们将51主方法中的代码分割在Setup和Loop方法中执行于是,我们将其分割为两个部分,将初始化部分放在Setup中执行,While(1)中的部分放在Loop中执行,如下所示:
//初始化部分
void setup()
{
pinMode(TN_Clk, INPUT); //设定时钟口为输入端口
pinMode(TN_ACK, OUTPUT);//设定ACK口为输出端口
digitalWrite(TN_ACK,HIGH);//在ACK口输出高电平
}
//采集部分
void loop()
{
digitalWrite(TN_ACK,LOW);
TN_ReadData(0x4c); //目标温度的第一个字节为0x4c
if((ReadData==0x4c)&&(ReadData==0x0d))//每帧的最后一个字节为0x0d
{
Target=TN_GetData_Target();
}
delay(1);
digitalWrite(TN_ACK,LOW);
TN_ReadData(0x66); //环境温度的第一个字节为0x66
if((ReadData==0x66)&&(ReadData==0x0d))//每帧的最后一个字节为0x0d
{
Temp=TN_GetData_Temp();
}
}
然后我们来看IIC数据传输的部分,大体逻辑我是这样理解的,时钟作为一个标志位,每当时钟高低电平改变的时候采用将1字节的数据存储起来并左移一位,直到出现结束标志位为止,这里我们要注意下51程序中while(TN_Clk);这样的地方。在这里我们TN_Clk代表的不是具体端口的高低电平所以要换成这样的写法while(val)
{
val = digitalRead(TN_Clk);//获取端口的高低电平
}
之后我们把这部分的代码转换过来,如下所示:
void TN_ReadData(char flag) //读数据
{
char i, j, k;
byte BitState = 0; //每次发七帧
for(k = 0; k < 7; k++)
{
for(j = 0; j < 5; j++) //每帧5个字节
{
for(i = 0; i < 8; i++)
{
int val = digitalRead(TN_Clk);//注意这里51是直接读端口号所以我们要进行转换
while(val)
{
val = digitalRead(TN_Clk);
}
BitState = digitalRead(TN_Data);
ReadData = ReadData << 1;
ReadData = ReadData | BitState;
while(!val)
{
val = digitalRead(TN_Clk);
}
}
}
if(ReadData == flag)k = 8;
}
digitalWrite(TN_ACK, HIGH);
}
再给这个程序加上串口输出的部分,我们这次的内容就大功告成了:)
int TN_Data = 15;
int TN_Clk = 14;
int TN_ACK = 13;
unsigned charReadData;
short Temp,Target;
void setup()
{
Serial.begin(9600);
pinMode(TN_Clk, INPUT);//
pinMode(TN_ACK, OUTPUT);
digitalWrite(TN_ACK,HIGH);
}
void loop()
{
digitalWrite(TN_ACK,LOW);
TN_ReadData(0x4c); //目标温度的第一个字节为0x4c
if((ReadData==0x4c)&&(ReadData==0x0d)) //每帧的最后一个字节为0x0d
{
Target=TN_GetData_Target();
}
delay(1);
digitalWrite(TN_ACK,LOW);
TN_ReadData(0x66); //环境温度的第一个字节为0x66
if((ReadData==0x66)&&(ReadData==0x0d)) //每帧的最后一个字节为0x0d
{
Temp=TN_GetData_Temp();
}
}
void SerialValue()
{
Serial.print("Target: ");
Serial.print(Target, DEC);
Serial.println(" C");
Serial.print("Temp: ");
Serial.print(Temp, DEC);
Serial.println(" C");
}
void TN_ReadData(char flag) //读数据
{
char i,j,k;
byte BitState = 0; //每次发七帧
for(k=0;k<7;k++)
{
for(j=0;j<5;j++) //每帧5个字节
{
for(i=0;i<8;i++)
{
int val= digitalRead(TN_Clk);
while(val)
{
val = digitalRead(TN_Clk);
}
//val = digitalRead(TN_Clk);
BitState= digitalRead(TN_Data);
ReadData= ReadData<<1;
ReadData= ReadData|BitState;
while(!val)
{
val = digitalRead(TN_Clk);
}
}
}
if(ReadData==flag)k=8;
}
digitalWrite(TN_ACK,HIGH);
}
int TN_GetData_Temp()
{
int Temp;
Temp=(ReadData<<8)|ReadData;
Temp = (float)Temp/16 - 273.15;
Temp=Temp*100; //温度值乘100,以方便计算小数点后两位
return Temp;
}
int TN_GetData_Target()
{
int Target;
Target=(ReadData<<8)|ReadData;
Target = (float)Target/16 - 273.15;
Target=Target*100; //温度值乘100,以方便计算小数点后两位
return Target;
}
最后我们来总结下51到Arduino程序转换需要注意的地方:
第一:端口定义的转换,因为端口取值的方式不同所以写法上要转换下,个人觉得从设计模式的角度上讲,51的端口取值方式虽然很方便,但是容易造成变量定义时的混淆,有时候多写几行代码未必是坏事。
第二:因为Arduino的基本结构包含Setup和Loop,51这里一般用一个死循环直接实现。所以这里要注意下程序哦分割。
第三:注意效率问题,比如Serial输出这样的方法消耗一定的时间,一次可能影响很小,但是如果套在多层循环中和需要速度的处理中影响会很大。有兴趣的朋友可以试试把串口输出的实际时间消耗。最后把程序模块化分割,冗余的逻辑。
其他方面我觉得程序移植起来还是很方便的,基本大部分51的代码都可以用Arduino来实现。本次因为这是测试代码所以有些小乱,我将会在后面的文章中详细讲解下如何整理和封装代码的步骤,让大家写起程序更加模块化:)
买10块干吗用~? 性能到底如何?好像是32K的处理器?好像到处都没说详细硬件性能啥的;
还是ARDUINO描述全面 外部晶震32K的,好像是16K的混合信号微控制器。。。具体能做什么还是不太懂。。。哎~~~~
看百度介绍控制器的说明好像主要还是低成本的数据采集处理 :)不错啊,我好想买的 不知道51的代码移植的效果如何,其实51应该是单片机比较入门的普及型机,很多大学的计算机系MSC51和Z80都是必修的专业课。。。
都能移植应该很强大了,而且这个东东貌似比51更强大? 本帖最后由 水乐天 于 2012-9-11 23:32 编辑
是的哈51的代码应该理论上都可以移植,这个东西普及了基本51市场就很小了:)我觉得用Arduino开发的最大好处是可以让新手和专家在开发时专注业务逻辑。
darkorigin 发表于 2012-9-11 20:03 static/image/common/back.gif
性能到底如何?好像是32K的处理器?好像到处都没说详细硬件性能啥的;
还是ARDUINO描述全面
16M内部振荡器 darkorigin 发表于 2012-9-11 20:10 static/image/common/back.gif
外部晶震32K的,好像是16K的混合信号微控制器。。。具体能做什么还是不太懂。。。哎~~~~
看百度介绍控制器 ...
16M........不是K...... darkorigin 发表于 2012-9-11 23:20 static/image/common/back.gif
不知道51的代码移植的效果如何,其实51应该是单片机比较入门的普及型机,很多大学的计算机系MSC51和Z80都是 ...
MCS51弱爆了 这个要顶~写得太详细了,对于初学launchpad,用Arduino开发的人来说太有用了!图文并茂,工具下载链接,程序代码及注释,注意事项,神马都有了,哈哈~~ 向LZ学习! ┏ωǒ┛菰独 发表于 2012-9-12 08:57 static/image/common/back.gif
MCS51弱爆了
确实MSC51很弱。但是51系列单片机貌似是出货量和存世量都很大的控制器。
代码神马的也都很经典啊。包括89c52啥的 也都是大量被应用的。
弱主要在性能上,但是强在便宜,毕竟周边元件也少,做一些简单应用完全够了,比如计算器,比如定时装置,比如其他设备的周边(比如显示模块的控制电路)也够了。
这个主控能移植51代码那么代码量上和例程上基本上真的是很广阔啊。。。哇咔咔
性能到底如何呢?16M的内部震荡,好像外部震荡频率还支持更高的? ┏ωǒ┛菰独 发表于 2012-9-12 08:57 static/image/common/back.gif
16M........不是K......
额。呵呵 手误。哈哈~~~SORRY:lol ┏ωǒ┛菰独 发表于 2012-9-12 08:57 static/image/common/back.gif
MCS51弱爆了
Z80好像还要弱。 现在好像没有看到神马产品了 水乐天 发表于 2012-9-11 23:31 static/image/common/back.gif
是的哈51的代码应该理论上都可以移植,这个东西普及了基本51市场就很小了:)我觉得用Arduino开发的最大好处 ...
是的,其实这也是程序设计的潮流,逐渐的通过强化IDE界面简化编程难度,使得程序员更多精力不会被牵制在那些冗余简单的代码上(比如C++ 和VC++ 到C# )不用自己画界面而采用组件的方式编程(当年TC2.0的时候UCDOS带的几个画图的例程和库文件我学了几个礼拜)
更多的让程序员去强化功能和逻辑(算法)上。
记得当年学MSC51时候 神马 基址变址寄存器 神马的搞死人了 用了C去做单片编程就已经是个里程碑(至少省略了初始化的几个堆栈操作)
页:
[1]
2