CCS和proteus联动仿真msp430控制四位数码管显示数字
前言
又是一年电子信息杯,每年单片机都有很多人放弃,我那时在环境搭建上耗了很多时间
这里分享一个我很早写的一个数码管显示的代码和整体流程,希望能对后来人有所帮助
一、软件基础
proteus和CCS(我用的是CCS9.3.0和proteus8.6)
下载和安装破解只要在CSDN上搜索就行,这里给出两个链接,如果你按流程安装有问题欢迎评论区指出
CCS
proteus
二、CCS生成需要的hex文件
1.建立工程和设置
file→new→CCS project 设置如下,选中芯片msp430g2553,创建工程名字(segdisplay),点击finish
正常建立以后点开main.c文件如下图所示
选中工程,右键,左键单击properties,左键单击Build界面如下所示
点击Steps,如下图所示
直接在Post-build steps中输入
“ C G T O O L H E X " − i " {CG_TOOL_HEX}" -i " CGTOOLHEX"−i"{BuildArtifactFileName}” -o “${BuildArtifactFileBaseName}.hex” -order MS -romwidth 16
在Description中输入
Create flash image: Intel-HEX
点击 左侧build下的MSP430 Hex Utility,勾选Enable MSP430 Hex Utility,如下图所示
点击apply and close。
2.写代码
代码如下(示例):
/* *************************************************************
* 电子信息杯初赛代码
*创建date 2019_12_03
* by hwk HeWenKang@bupt.edu.cn
*********************************************************** */
/* *************************************************************
写于2020_12_11
回看这些代码真是黑历史-=也不知道这个代码能不能正常运行,如果不行多看看引脚定义有没有问题
建议早点看中断内容,脱离轮询的笨办法;在src里面多创建一些文件,按功能分类放;多些注释,养成良好习惯;多用define,增强代码的可移植性;函数命名多用下划线和英文
测频率和占空比可以用定时器捕获,但是proteus仿真有点问题,管脚和代码里对应不上,可能存在进不去中断的情况
单片机路漫漫其修远兮,加油冲冲冲
*********************************************************** */
#include <msp430g2553.h>
/* *************************************************************
* 1ms延时函数
* 延时函数,具体延时的值根据主时钟频率改变而改变,调节内部i大小即可
* by hwk HeWenKang@bupt.edu.cn
*********************************************************** */
void delay_1ms(void)
{
unsigned int i;
for (i = 0; i<40; i++)
;
}
/*******************************************************************
* nms延时函数
* 延时函数,具体延时的值根据主时钟频率改变而改变
* by hwk HeWenKang@bupt.edu.cn
*******************************************************************/
void delay_nms(unsigned int k)
{
unsigned int i = 0;
for (i = 0; i <k ; i++)
delay_1ms();
}
/*******************************************************************
* 引脚初始化函数
* 设置引脚输入输出
* by hwk HeWenKang@bupt.edu.cn
*******************************************************************/
void GPIO_Init(void)
{
P1OUT = 0;//P1初始值为0x00;
P1DIR|=BIT1+BIT2+BIT3+BIT4+BIT5; // P1.1、p1.2、P1.3、P1.4设为输出(置1)
P1DIR&=~BIT7;
P2OUT = 0;//P2初始值为0x00;
P2DIR|=BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7; // P2设为输出(置1)
}
/* ******************************************************************
* 7位数码管数字输出辅助函数
* m==3处是小数点,所以比较特殊,原理就是扫频,m是第几位,n是该位数字
* by hwk HeWenKang@bupt.edu.cn
*********************************************************************/
void segprintf(unsigned int m,unsigned int n){
P1OUT=0;
if(m==1)
{P1OUT = BIT1;P2OUT =0XFF;
}
else if(m==2)
{P1OUT = BIT2;P2OUT =0XFF;
}
else if(m==3)
{ P1OUT = BIT3;P2OUT =0XFF;
}
else if(m==4)
{P1OUT = BIT5;P2OUT =0XFF;
}
else
P1OUT=0;
if(m==3)
{ switch(n){
case 0: P2OUT=BIT1;break;
case 1: P2OUT=BIT1+BIT2+BIT3+BIT4+BIT7;break;
case 2: P2OUT=BIT2+BIT5;break;
case 3: P2OUT=BIT2+BIT3;break;
case 4: P2OUT=BIT3+BIT4+BIT7;break;
case 5: P2OUT=BIT3+BIT6;break;
case 6: P2OUT=BIT6;break;
case 7: P2OUT=BIT1+BIT2+BIT3+BIT4;break;
case 8: P2OUT =0;;break;
case 9: P2OUT=BIT3;break;
}}
else
{
switch(n){
case 0: P2OUT=BIT0+BIT1;break;
case 1: P2OUT=BIT0+BIT1+BIT2+BIT3+BIT4+BIT7;break;
case 2: P2OUT=BIT0+BIT2+BIT5;break;
case 3: P2OUT=BIT0+BIT2+BIT3;break;
case 4: P2OUT=BIT0+BIT3+BIT4+BIT7;break;
case 5: P2OUT=BIT0+BIT3+BIT6;break;
case 6: P2OUT=BIT0+BIT6;break;
case 7: P2OUT=BIT0+BIT1+BIT2+BIT3+BIT4;break;
case 8: P2OUT =BIT0 ;break;
case 9: P2OUT=BIT0+BIT3;break;
}
}
delay_nms(1);
// P1OUT=0;
// P2OUT=0;
}
/* ******************************************************************
* 频率输出函数
* 待补充
* by hwk HeWenKang@bupt.edu.cn
*********************************************************************/
int frequency(void)
{
return(1314);
}
/* ******************************************************************
* 占空比输出函数
* 待补充
* by hwk HeWenKang@bupt.edu.cn
*********************************************************************/
int dutycycle(void)
{
return (1413);
}
/* ******************************************************************
* 7位数码管数字输出函数
* 输入4位数k,函数取每一位的数,通过函数segprintf(a,b)将每一位在对应位输出
* by hwk HeWenKang@bupt.edu.cn
*********************************************************************/
void printfseg(unsigned int k)
{
unsigned int a;
unsigned int b;
b=k/1000;
a=4;
segprintf(a,b);
k=k-1000*b;
b=k/100;
a=3;
segprintf(a,b);
k=k-100*b;
b=k/10;
a=2;
segprintf(a,b);
k=k-10*b;
b=k;
a=1;
segprintf(a,b);
}
/* ******************************************************************
* 主函数
*尽量把函数写在外面,最好写在别的文件里面然后include,main函数越简单越好
* by hwk HeWenKang@bupt.edu.cn
*********************************************************************/
int main(void)
{
WDTCTL = WDTPW | WDTHOLD;// 关闭看门狗,我也不知道为什么,但基本上都有这个代码,好像是为了防止程序跑飞
// BCSCTL1 = CALBC1_1MHZ;
// DCOCTL = CALDCO_1MHZ;
// BCSCTL2 = SELM_0 | DIVM_0 | DIVS_3;
GPIO_Init();
//定义引脚功能
unsigned int f=0;
unsigned int z=0;
f=frequency();
z=dutycycle();
while(1) //用中断可以节省资源,但是不太会,用轮询方式消耗资源达到效果,反正他不看源代码:(
{
while(1) //循环A
{
if((P1IN & BIT7) == BIT7)
printfseg(f);
else
{
while(1)
{
if((P1IN & BIT7) == BIT7)
break;
else
;
}
break;
}
}
while(1) //循环B
{
if((P1IN & BIT7) == BIT7)
printfseg(z);
else
{
while(1)
{
if((P1IN & BIT7) == BIT7)
break;
else
;
}
break;
}
}
} //最大while的后括号
}
完成以后点击左侧小锤子build 工程,build finish以后显示如下
三、proteus搭建电路与载入hex
这部分比较简单,照着图片找元件搭就行,搭建出来的电路效果如下图所示,我的主页里也给出这个电路的工程文件proteus_seg。
右键芯片,选择编辑元件,选择program file,找到之前在CCS中工程目录debug目录下的.hex文件
打开,确定,然后点左下角运行
总结
代码里面当时测试有一个bug,发现当输入的数字是0开头时,数码管显示会显示不一样的数,就是说如果return的z是0520,显示的就是0336,如果是520,显示的就是0520,这点要注意一下。
然后代码显示是保留2位小数的显示,具体逻辑可以看源代码,注释还行,应该看得懂。
后面还会遇到proteus仿真问题,比如说定时器捕获中断进不去,串口没有输出,这些在烧录硬件时都不会遇到,但是烧录硬件也有它的问题,测试起来没有仿真方便。
最后附上我去年电子信息杯在B站的两个视频,还有很多腾讯视频的视频我就不发了,你们去腾讯视频搜电子信息杯应该就能搜到我们那一级的黑历史。
利用IAR生成.hex文件并在Proteus中运行
2020F134_msp430演示视频_电子信息杯
再强调一下我在代码前面写的一段话
建议早点看中断内容,脱离轮询的笨办法;在src里面多创建一些文件,按功能分类放;多些注释,养成良好习惯;多用define,增强代码的可移植性;函数命名多用下划线和英文
测频率和占空比可以用定时器捕获,但是proteus仿真有点问题,管脚和代码里对应不上,可能存在进不去中断的情况
单片机路漫漫其修远兮,加油冲冲冲
本文地址:https://blog.csdn.net/weixin_43812576/article/details/111087056