无论您是 MSP430 的设计老手,还是初涉 MSP430 应用设计,8 月 30 日到 9 月 16 日,快来分享您认为对您设计有用的资料文档!每一位分享者将获赠一块 MSP430 LaunchPad + MSP430 电容触摸 BoosterPack 。


分享内容: 资料可来源于 TI 官方网站或自创内容,且和MSP430相关
分享方式:
获赠标准:一个 ID 仅拥有一个获赠机会
我们期待您的给力分享!
希望 TI 官方 MSP430 社区为大家提供一个学习、分享的平台!
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
无论您是 MSP430 的设计老手,还是初涉 MSP430 应用设计,8 月 30 日到 9 月 16 日,快来分享您认为对您设计有用的资料文档!每一位分享者将获赠一块 MSP430 LaunchPad + MSP430 电容触摸 BoosterPack 。


我们期待您的给力分享!
希望 TI 官方 MSP430 社区为大家提供一个学习、分享的平台!
最近在看 嵌入式实时操作系统,因为之前TI公司对大学的支持,用了很长时间的MSP430做东西,所以在学习操作系统移植时选用了使用顺手的MSP430,期间要用到相关的430汇编知识,所以要熟悉怎么在IAR环境下使用C与汇编 混合编程的方式,开始找不到好的切入点,后来发现原来在TI网站,和IAR安装目录下有对相关的规范讲解,和使用方法,在这里我分享一下时常被忽略的 IAR 中的汇编帮助文档。
本人学生,一直接触单片机学习和开发,之前也有一些使用过MSP430LaunchPad开发板,不过是同学的,用起来非常好用,资料丰富,希望能都得到一块。
用的开发软件是ti官网上现在的CCS5,安装时候要注意解压路径和安装路径不能有中文名称,ccs5能够在线进行仿真,很好用。
ccs5下载地址:http://processors.wiki.ti.com/index.php/Download_CCS 下载相应支持系列的版本的CCS。
对MSP430LaunchPad开发资料用了MSP430x2xx User Guide.pdf,MSP-EXP430G2 LaunchPad Experimenter.pdf,msp430g2553.pdf开发文档
下载地址ti官网:http://www.ti.com/lsds/ti/microcontroller/16-bit_msp430/overview.page
还用就是ti公司提供的一个代码示例 MSP430G2xx3 Code Examples 里面有很多的例子。
http://www.ti.com/lsds/ti/microcontroller/16-bit_msp430/code.page
最后提供一个我帮人写的一个代码程序,有注释,用于寝室安防方面的。
ti官网上有提供应用笔记,非常好的资料,最好最准确的资料都是来自官网的。
干才看到一个适合初学者的 ppt 与大家分享一下
咱是做硬件设计的,发几个MSP430F单片机的硬件资料:
PROTEL99SE SCH\PCB文件,网上下载。
芯片封装、布线例子都在这里了。
看图上的标志,是TI原装的噢!


LaunchPadG2553+蜂鸣器演奏最炫民族风http://bbs.eeworld.com.cn/thread-342427-1-1.html
精华帖!本人原创代码,进入此帖即可下载。另有430G2553的音长音高对照表。有了此表任何歌曲都可演奏
同学申请到过一块LaunchPad,借他的学习了一个暑假,430这类单片机给我的是全新体验,尤其是时钟系统以及定时器系统,之后一直在关注Launchpad的发展,最近了解到又推出了Energia,类似于Arduino,这使得Launchpad变的更为简便和有趣。所以想申请一块,望能予以批准。
附上我在学习Launchpad时的学习资料,正是这些资料让我一步步了解了MSP 430,资料不在于多,关键在于自己边看例程和Datasheet 边调试,这样才能循序渐进,希望对大家有帮助!
zhan.renren.com/msp430 这是msp430的人人小站,很不错哦
关于MSP430,自己前一段时间参加过TI在武汉的培训会,包括C2000,加上以前对C2000的学习,由于自己是大学生,最近还和队友对6638进行了设计焊接,对430有一定的了解,再次分享一下自己的一点资料。
另外,CCS 5.2中有很多430的资料,很齐全的。
非常期待得到这份赠送品,大家一起学习!
热转印法手工制作MSP430F5527双面核心板
【TI杯大赛点滴】E题 激光枪自动射击装置 获奖作品展示(四川赛区一等奖)论文见附件
对于每一个430的初学者来说,如果没有名师指点,我们是多么渴望能有专业的视频来自学。
经过多方收集,我终于找到了MSP430教学视频。主讲人是哈理工的研究生(现在自己开公司,教学试验箱类,我很敬佩他),我和同学51、Altium Designer、FPGA等等很多,都是看他的视频学会的,而且他讲的质量很高,不像那些所谓的大学教授,只会讲些理论,他录制的视频里有理论、程序现场编写、和对不可预见的问题分析方法等。
由于视频比较大,没法在这里上传附件,所以只留下邮箱zmbamboo@163.com,有兴趣的朋友可以发邮件索要。下面附上MSP430教学视频的内容列表,供大家选择。
第一部分 硬件结构
第一讲 概述
第二讲 复位、中断和IO
第三讲 异步通信接口1
第四讲 异步通信接口2
第五讲 定时器
第六讲 FLASH
第七讲 ADC12
第二部分 软件使用
第三部分 基础程序
第一讲 入门和低功耗
第二讲 时钟和IO
第三讲 比较器和定时器和ADC
第四部分 模块程序
第一讲 控制电路和流水灯
第二讲 键盘
第三讲 蜂鸣器和数码管
第四讲 1602液晶和电平转换
第五讲 EEPROM和18B20和DS1302
第六讲 RS232和RS485
第七讲 USB接口
第八讲 ADC和DAC
发现单片机的定时器一直会是作品设计中很有用的一个外设,像产生PWM波控制电机,测量信号频率,VCA控制都可以用定时器很方便的实现,在这里分享一份launchpad定时器A的资料,可以很容易了解定时器A的四种工作模式,掌握相关寄存器的配置。之前就是靠着它在电赛的培训活动中完成了程控放大的
我觉得该文档相当好,特别适合初学者,题目是“MSP430_C语言例程注释详”
下载地址是wenku.baidu.com/.../df65f58102d276a200292e53.html
本章选择了一些简单的C语言程序例题,这些程序的结构简单,编程技巧不多,题目虽然
简单,但是非常适合入门单片机的学习者学习MSP430 单片机的C 语言编程。
如下列出了C语言例题运行的MSP430F149实验板硬件资源环境,熟悉这些硬件资源,对
于理解程序非常重要。
(1)数码管:
左侧数码管与P5口相连,a~g,h对应P5.0~P5.7
右侧数码管与P4口相连,a~g,h对应P4.0~P4.7
(2)发光二极管
8 个发光二极管与P3 口连接
(3)按钮:
左侧8个按钮与P2口相连,引脚号标在按钮上方
右侧8个按钮与P1口相连,引脚号标在按钮上方
(4)P2.3引脚还是模拟比较器输入
(5)P6.0,P6.1引脚连接模拟量电位器,用于模拟量实验
我觉得该文档相当好,特别适合初学者,题目是“430单片机__极端详细__应用程序_中文讲解”
MSP430系列十六位超低功耗单片机
教学实验系统实验教程
从开始介绍到动手操作,一共分为15个实验,可以熟悉MSP430在各种模块中的使用,培养动手能力,值得一看
我感觉这个文档是非常好的,我最初学习单片机是参加学校的竞赛。但是感觉这个文档帮助很大。由于现在没有自己的板子,已经有一段时间没有学习了,很希望可以获得launchpad。
做USB开发,参考价值很大
本人第一次做USB开发,用的芯片是MSP430F5529,在TI官网下的开发资料,包括源代码。
因为我的项目USB数据交互量比较小,所以选择了比较简单的HID模式。
http://wenku.baidu.com/view/512793c189eb172ded63b711.html?from_page=view&from_mod=download
这个是我学习时的第一个学习文档,当时老师说得挺好的
本作品是本人参加2012年湖南省TI杯电子设计大赛的作品,采用了PID控制算法,对AD采样数据运用了中值滤波算法,达到了很好的效果~~
继续跟一个帖子以符合斑竹兄弟的跟贴要求。
对于想学习MSP430单片机的新手来说,TI已经为我们做好了各种准备,她在大学计划准备了《MSP430教学光盘》资料供我们下载学习:
www.ti.com/.../msp430.html(请在浏览器输入这个url)
该连接提供了MSP430器件硬件原理、开发工具介绍、各个模块软件编程以及实际编程应用,甚至把汇编指令参考都汇聚到一起。这些资料
为我们开发MSP430产品提供全方位的技术支持,指导在MSP430单片机开发的道路上行进。
Chapter 1 Introductory Overview
Chapter 2 Software Development Tools
Code Composer Essentials v3: Overview
Composer Essentials v3: Creating a project
Code Composer Essentials v3: Code Debugging
Code Composer Essentials v3: Laboratory
IAR Embedded Workbench™
Chapter 3 Hardware Development tools
Chapter 4 MSP430 Architecture
Chapter 5 Device Systems and Operating Modes
Chapter 6 General Purpose Input/Output
Chapter 7 Timers
Description of clock signals
Laboratories
Chapter 8 LCD Controller
Chapter 9 Data Acquisition
Introduction
Operational Amplifiers
A/D Conversion Introduction
SAR ADC
SD ADC
Comparator-Based Slope ADC
Comparator_A
Chapter 10 Digital-to-Analogue Conversion
Chapter 11 Direct Memory Access (DMA)
Chapter 12 Hardware Multiplier
Chapter 13 Flash Programming
Chapter 14 Communications
Introduction
USART Module
USCI Module
USI Module
Chapter 15 Advanced Laboratories
RoboSapien powered by MSP430
RF link using the eZ430-RF2500
MSP430 assembly language tutorial: MSP430 CPU
MSP430 assembly language tutorial: MSP430X CPU
MSP430 assembly language tutorial: Instructions
MSP430 assembly language tutorial: Creating an assembly project with CCE
一般我开发TI的处理器,都会重点研究APPLICATION文档,TI的中文网站上提供了不少由TI的工程师翻译过来的技术文档,
由Hanson He Loops Lu提供的《16 位MSP430G 系列微处理器的使用扩展》给我不少启迪:
该文档提供了基于MSP430G2231一个完整的开发示例:从系统框图、原理图以及DAC、soft Uart、BSL关键程序代码到汽车车窗
应用完整工程。完整的汇编级代码工程,让我们后续开发MSP430不再无从下手。
非常渴望这个开发套件,TI的兄弟,我可一直在支持你们啊!!!
天天看帖,天天邮箱都是满的。MSP430....MSP430 LaunchPad的诱惑力太大了呀!!!!500封顶!兄弟们快点呀。到了最后的疯狂了!!
看看附件的小视频。
我觉得还是TI官网的用户手册和数据手册最实用了。。归根到底,还是这两个东西。。虽然是我英文不怎么好,但我觉得这两个手册很不错。对刚接触430编程的人员来说,是非常好的。即准确。又全面。。
http://www.ti.com.cn/lsds/ti_zh/microcontroller/16-bit_msp430/hardware_and_software.page
MSP430的一个强大功能是其定时器A,每一款430都有定时器A模块,部分有其增强模块,掌握了定时器A,就掌握了一个强大的外设。以下为定时器A的一些应用实例,相信可以给大家帮助。
MSP430F413芯片中含有TimerA3模块,如图1-2所示。其常用的外引线有三条:TACLK、TA1和TA2。
TACLK:定时器_A输入时钟(48脚),与P1.6和ACLK输出共用同一引脚。
TA1:定时器_A的第一通道输入、输出引脚(51脚)。捕获方式:CCI1A输入;比较方式:OUT1输出。
TA2:定时器_A的第二通道输入、输出引脚(45脚)。捕获方式:CCI2A输入;比较方式:OUT2输出。
1.定时器A功能及结构
定时器A基本结构是一个十六位计数器,由时钟信号驱动工作,结构框图如图4-1所示。
图4-1 定时器A结构图
定时器A具有多种功能,其特性如下:
(1)输入时钟可以有三种选择,可以是慢时钟(ACLK)、快时钟(SMCLK与单片机主时钟同频)和外部时钟。
(2)能产生的定时中断、定时脉冲和 PWM(脉宽调制)信号,没有软件带来的误差。
(3)不仅能捕获外部事件发生的时间,还可选择触发脉冲沿(由上升沿或下降沿触发)。
定时器A功能模块主要包括:
(1)计数器部分:输入的时钟源具有4种选择,所选定的时钟源又可以1、2、4或8分频作为计数频率,Timer_A可以通过选择4种工作模式灵活的完成定时/计数功能。
(2)捕获/比较器:用于捕获事件发生的时间或产生时间间隔,捕获比较功能的引入主要是为了提高I/O 端口处理事务的能力和速度。不同的MSP430单片机,Timer_A模块中所含有的捕获/比较器的数量不一样,每个捕获/比较器的结构完全相同,输入和输出都取决于各自所带控制寄存器的控制字,捕获/比较器相互之间完全独立工作。
(3)输出单元:具有可选的8种输出模式,用于产生用户需要的输出信号,支持PWM输出。
2.定时器工作模式
(1)停止模式:停止模式用于定时器暂停,并不发生复位,所有寄存器现行的内容在停止模式结束后都可用。当定时器暂停后重新计数时,计数器将从暂停时的值开始以暂停前的计数方向计数。例如,停止模式前,Timer_A工作于增/减计数模式并且处于下降计数方向,停止模式后,Timer_仍然工作于增/减计数模式,从暂停前的状态开始继续沿着下降方向开始计数。如果不需这样,则可通过TACTL中的CLR控制位来清除定时器的方向记忆特性。
(2)增计数模式:捕获/比较寄存器CCR0用作Timer_A增计数模式的周期寄存器,因为CCR0为16位寄存器,所以该模式适用于定时周期小于65536的连续计数情况。计数器TAR可以增计数到CCR0的值,当计数值与CCR0的值相等(或定时器值大于CCR0的值)时,定时器复位并从0开始重新计数。增计数模式的计数过程如图4-2所示。通过改变CCR0值,可重置计数周期。
图4-2增计数模式示意图
(3)连续计数模式:在需要65536个时钟周期的定时应用场合常用连续计数模式。定时器从当前值计数到单增到0FFFFH后,又从0开始重新计数如图4-3所示。
图4-3 连续计数模式
(4)增/减计数模式
需要对称波形的情况经常可以使用增/减计数模式,该模式下,定时器先增计数到CCR0的值,然后反向减计数到0。计数周期仍由CCR0定义,它是CCR0计数器数值的2倍。计数器的计数过程如图4-4所示。
图4-4增/减计数模式
3.增计数模式应用举例
增计数最大值存储器在CCR0,该值计算方法如下:选用辅助时钟时,ACLK频率f=32768Hz,周期T=1/32768,若选用250ms中断,则CCR0值应为:
转换成十六进制数后N=2000(H)
MSP430F413单片机定时器A构成的时钟小系统程序清单如下:
/***************************************************
* 文件名称:MSP413C语言定时程序
* 文件说明:用MSP430F413定时器A作为定时中断源。
***************************************************/
#include <msp430x41x.h>
/*****************************************************
* 文件说明:LCD 模块
*****************************************************/
#define LCD_IN_USE 10
/******************************************************
* 数据定义七段译码表
*****************************************************/
const unsigned char NUM_LCD[17]={
0xd7, 0x06, 0xe3, 0xa7, 0x36, //'0'~ '4'
0xb5, 0xf5, 0x07, 0xf7, 0xb7, //'5' ~ '9'
0x77, 0xf4, 0xd1, 0xe6, 0xf1, // 'A'~ 'E'
0x71, 0x00}; // 'F','全熄'
unsigned char lcd_Buf[LCD_IN_USE]; // 自定义显示缓冲区,用于要显示的数据
unsigned int cont,y0,y1,y2; //秒、时、分存储变量
/*******************************************************
* LCD模块初始化
*******************************************************/
void init_LCD(void)
{
char tmpv;
BTCTL = BT_fLCD_DIV32; // set LCD 时钟
P5SEL = 0xfc; // 置为外围模块
LCDCTL = LCDON+LCD4MUX+LCDP1; // 4Mux 模式
for (tmpv = 0;tmpv<10;tmpv++)
{
LCDMEM[tmpv] = 0x00; //clear LCD
}
}
/*******************************************************
* LCD清零模块
*******************************************************/
void cl_LCD(void)
{
char tmpv;
for (tmpv = 0;tmpv<10;tmpv++)
{
LCDMEM[tmpv] = 0x00; //clear LCD
}
}
/****************************************************
* 更新LCD缓冲区的内容,把数据显示到LCD
****************************************************/
void lcd_Display(void)
{
char tmpv;
lcd_Buf[0]=y2/10; lcd_Buf[1]=y2%10;
lcd_Buf[2]=16;
lcd_Buf[3]=y1/10; lcd_Buf[4]=y1%10;
lcd_Buf[5]=16;
lcd_Buf[6]=y0/10; lcd_Buf[7]=y0%10;
lcd_Buf[8]=16; lcd_Buf[9]=16;
for(tmpv=0;tmpv<LCD_IN_USE-1;tmpv++)
{
LCDMEM[tmpv] = NUM_LCD[lcd_Buf[tmpv]]; //更新LCDMEM中的内容
}
}
/***********************************************************
*定时器A中断服务程序
************************************************************/
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A(void)
//interrupt[TIMERA0_VECTOR] void Timer_A (void)
{
cont=cont+1;
if(cont==4)
{
cont=0;
y0=y0+1; //秒加1
if(y0==60)
{
y0=0; y1=y1+1; //60秒为1分,分加1
if(y1==60)
{
y1=0; y2=y2+1; //60分为1小时,小时加1
if(y2==24)
{y2=0 ; //24小时再清零
}
}
}
cl_LCD();
lcd_Display();
_NOP();
}
}
void init_TA(void) //初始化定时器A
{
TACCR0 = 0x2000;
TACTL = TASSEL0 + TACLR; // ACLK, 清零Tar
TACCTL0 = CCIE; // 中断使能CCR0
TACTL |= MC0; // 设置增模式启动定时器A
}
/***********************************************************
*主程序
************************************************************/
void main(void)
{
WDTCTL = WDTPW +WDTHOLD; // 关WDT
SCFQCTL |= SCFQ_4M; // 设定主时钟为4MHz
init_LCD();
init_TA() ;
_EINT(); // 使能中断
cont=0; y0=0; y1=0; y2=0;
for (;;)
{
_BIS_SR(CPUOFF); //关CPU
_NOP(); // 调试程序使用
}
}
4.输出单元
定时器A的输出单元输出模式有8种,增计数模式下输出模式如图4-5所示。
图4-5输出模式示意图
各模式说明如下:
(1)输出模式0—输出模式:输出信号OUTx由每个捕获/比较模块的控制寄存器CCTLx中的OUTx位定义,并在写入该寄存器后立即更新。最终位OUTx直通。
(2)输出模式1—置位模式:输出信号在TAR等于CCRx时置位,并保持置位到定时器复位或选择另一种输出模式为止。
(3)输出模式2—PWM翻转/复位模式:输出在TAR的值等于CCRx时翻转,当TAR的值等于CCR0时复位。
(4)输出模式3—PWM置位/复位模式:输出在TAR的值等于CCRx时置位,当TAR的值等于CCR0时复位。
(5)输出模式4—翻转模式:输出电平在TAR的值等于CCRx时翻转,输出周期是定时器周期的2倍。
(6)输出模式5—复位模式:输出在TAR的值等于CCRx时复位,并保持低电平直到选择另一种输出模式。
(7)输出模式6—PWM翻转/置位模式:输出电平在TAR的值等于CCRx时翻转,当TAR值等于CCR0时置位。
(8)输出模式7—PWM复位/置位模式:输出电平在TAR的值等于CCRx时复位,当TAR的值等于CCR0时置位。
选用增计数模式、输出模式7产生的PWM输出波形如图4-6所示。
图4-6 输出模式7产生PWM输出波形
5.输出单元应用举例
例1.Timer_A用增模式在P1.2/2.0产生两路PWM输出。CCR0计数值为512,通过设定CCR1和CCR2值,定义两路输出脉宽。使用32kHz ACLK作为TACLK,定时器周期为15.625ms,P1.2占空比为75%、P2.0占空比为25%。 ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO = 32xACLK = 1.048576Mhz。外部晶振接于XIN和XOUT。
#include <msp430x41x.h>
void main(void)
{
WDTCTL = WDTPW +WDTHOLD; // 关WDT
TACTL = TASSEL0 + TACLR; // ACLK, 清零Tar
CCR0 = 512; // PWM 周期
CCTL1 = OUTMOD_7; // CCR1 reset/set模式
CCR1 = 384; // CCR1 PWM 任务周期
CCTL2 = OUTMOD_7; // CCR2 reset/set模式
CCR2 = 128; // CCR2 PWM 任务周期
P1DIR |= 0x04; // P1.2 输出
P1SEL |= 0x04; // P1.2 TA1模式
P2DIR |= 0x01; // P2.0 输出
P2SEL |= 0x01; // P2.0 TA2模式
TACTL |= MC0; // 增模式启动Timer_A
for (;;)
{
_BIS_SR(LPM3_bits); // 进入LPM3省电模式
_NOP(); // C-spy使用
}
}
一、直流电机驱动电路工作原理
1)直流电机转向原理
直流电机一般采用H桥驱动电路,如图5-1所示。
图5-1 直流电机驱动原理图
同步改变对角开关管通断状态,就改变了流过电机的电流方向,也就改变了直流电机的转动方向,达到了控制正、反转的目的。电路工作状态表如表5-1所示。
表5-1H桥电机控制状态表
|
PWM |
A |
B |
电机运行状态 |
|
0 |
× |
× |
停转 |
|
1 |
0 |
0 |
停转 |
|
1 |
0 |
1 |
反转 |
|
1 |
1 |
0 |
正转 |
|
1 |
1 |
1 |
停转 |
注:“0”代表低电平;“1”代表高电平。
由表5-1可知,H桥电路将电机转动方向控制转化为A、B两端的电平控制,便于与单片机接口实现电机转向控制。
2)直流电机转速控制原理
控制直流电动机所加电压即可控制电机转速。直接调整图5-1中直流电机所加电压VDD虽然可调整电机转速,但其主要缺点是效率低。为了提高效率,通常采用占空比可调矩形波控制电机转速,即PWM(脉冲宽度调制)波调速。PWM信号示意如图5-2所示,图中T为设定的脉冲周期,在驱动电机过程中确定不变;t为脉冲的高电平时间,占空比d = t /T。 将其加于图5-1电路的PWM端,电机转速与PWM信号占空比成正比。
图5-2PWM信号示意图
PWM波产生方法有多种,本设计中为了简化电路,直接使用单片机内定时器A产生PWM控制电机转速。
3)电机驱动专用芯片L293D简介
图5-1所示H桥电路仅是原理电路,要转化为实用电路还要做许多工作,因此实际应用中很少采用。
L293D是集成电路芯片,片内含有双H 桥驱动器,引脚图如图5-3所示。输入小电流控制信号,输出高电压、大电流驱动信号。用逻辑电平控制、驱动感性负载(比如继电器,直流电机和步进电机等)。通过改变芯片控制端的输入电平,即可以对电机进行正反转操作。芯片具有1.2A峰值输出电流通道,使用简易便。其额定工作电流为1A,最大可达1.5A,Vss电压最小4.5V,最大可达36V;Vs电压最大值也是36V。
L293D是16引脚塑料封装,中间的4个引脚是短路的(为了散热), L293D的Vss和Vs电源端可分别接入芯片电源和电机驱动电源。
图5-3 L293D引脚图 图5-4 L293D功能示意图
L293D功能示意图如图5-4所示(对应20引脚芯片)。
L293D使能、输入引脚和输出引脚的逻辑关系如表5-2所示。
表5-2 引脚和输出引脚的逻辑关系
|
EN A(B) |
IN1(IN3) |
IN2(IN4) |
电机运行情况 |
|
H |
H |
L |
正转 |
|
H |
L |
H |
反转 |
|
H |
同IN2(IN4) |
同IN1(IN3) |
快速停止 |
|
L |
X |
X |
停止 |
H-桥电路的输入量可以用来设置电机转动方向,使能信号可以用于脉宽调整(PWM),实现电机转速控制。L293D将2个H-桥电路集成到1片芯片上,这就意味着用1片芯片可以同时控制2个直流电机。每1个直流电机需要3个控制信号EN1、IN1、IN2,其中EN1是使能信号,IN1、IN2为电机转动方向控制信号,IN1、IN2分别为1,0时,电机正转,反之,电机反转。选用一路PWM连接EN1引脚,通过调整PWM的占空比可以调整电机的转速。
4)直流电机驱动电路
驱动电路如图5-5所示,单片机PIO端口线P1.0、P1.1驱动光电隔离器中发光二极管,控制光电三极管。输入为高电平时,三极管饱和导通,反之截止。当P1.0为高电平、P1.1位低电平时,L293D的IN4为高、IN3为低电平,OUT4为高、OUT3位低电平,电机正转;反之,当P1.0位低、P1.1为高电机反转;当P1.0、P1.1电平同时为高或低时,电机停转,实现了电机转向控制。
E2是OUT4、OUT3的使能端,高电平有效。当在E2端加PWM信号时,可实现调速。高速转动对应的PWM信号占空比为1;次高速占空比为0.75;中速转动占空比为0.5;低速转动占空比为0.25。
PWM信号由MSP430F413单片机定时器A产生。光电隔离器在传送信号同时实现了电平转换,将高电压(6-9V)电机驱动电路与低电压(4.5V)单片机电路隔离,消除了干扰。注意两电路地线标志不同,焊接时不能连接。
图5-5直流电机驱动电路
二、直流电机控制系统硬件设计
直流电机控制系统电路如图5-6所示,是在时钟小系统基础上加入直流电机驱动电路、按键和功能选择开关电路。功能选择开关在上是电机驱动功能,在下是时钟计时功能。
图5-6直流电机控制系统
当开关拨到时钟计时功能时,可以通过秒、分、时三个按键来调节时钟显示固定数字,然后按确定键,时钟便可以在设定时间的基础上开始计时,另外还可以按左侧的复位键,给时钟清零。
当开关拨到电机驱动功能时,电机默认为正转,占空比为0.5,然后通过按键可分别实现:占空比为1的正转,占空比为0.5的正转,占空比为0.5的反转,占空比为1的反转。注意由于按键的局限性,实现电机以上四种旋转的情况要长按按键,一旦松手电机将按默认的占空比为0.5的正传旋转。
本系统中使用两套电源供电,其一是单片机系统电源,考虑到时钟的低功耗,使用3.6伏手机电池供电;其二是直流电机电源,直流电机工作时比较耗电,所以可大容量电池或5V直流电源供电。
5V直流稳压电源电路如图5-7所示。
图5-7 直流稳压电源电路
三、程序设计
1)电机控制程序
直流电机变速驱动小系统程序是在时钟小系统程序基础上增加了相应的初始化和电机驱动控制程序。初始化部分加于_EINT()语句之后,电机驱动部分加于定时中断程序中y0=y0+1语句之后。程序清单如下所示:
/***************************************************
* 文件名称:MSP413C语言定时和直流电机控制程序
* 文件说明:用MSP413看门狗定时器作为定时中断源。
***************************************************/
#include <msp430x41x.h>
/*****************************************************
* 文件说明:LCD 模块
*****************************************************/
#define LCD_IN_USE 10
/******************************************************
* 数据定义七段译码表
*****************************************************/
const unsigned char NUM_LCD[17]={
0xd7, 0x06, 0xe3, 0xa7, 0x36, //'0'~ '4'
0xb5, 0xf5, 0x07, 0xf7, 0xb7, //'5' ~ '9'
0x77, 0xf4, 0xd1, 0xe6, 0xf1, // 'A'~ 'E'
0x71, 0x00}; // 'F','全熄'
unsigned char lcd_Buf[LCD_IN_USE]; // 自定义显示缓冲区,用于要显示的数据
unsigned int cont,y0,y1,y2,s_num; //秒、时、分存储变量
/*******************************************************
* LCD模块初始化
*******************************************************/
void init_LCD(void)
{
char tmpv;
BTCTL = BT_fLCD_DIV32; // set LCD 时钟
P5SEL = 0xfc; // 置为外围模块
LCDCTL = LCDON+LCD4MUX+LCDP1; // 4Mux 模式
for (tmpv = 0;tmpv<10;tmpv++)
{
LCDMEM[tmpv] = 0x00; //clear LCD
}
}
/*******************************************************
* LCD清零模块
*******************************************************/
void cl_LCD(void)
{
char tmpv;
for (tmpv = 0;tmpv<10;tmpv++)
{
LCDMEM[tmpv] = 0x00; //clear LCD
}
}
/****************************************************
* 更新LCD缓冲区的内容,把数据显示到LCD
****************************************************/
void lcd_Display(void)
{
char tmpv;
lcd_Buf[0]=y2/10;
lcd_Buf[1]=y2%10;
lcd_Buf[2]=16;
lcd_Buf[3]=y1/10;
lcd_Buf[4]=y1%10;
lcd_Buf[5]=16;
lcd_Buf[6]=y0/10;
lcd_Buf[7]=y0%10;
lcd_Buf[8]=16;
lcd_Buf[9]=16;
for(tmpv=0;tmpv<LCD_IN_USE-1;tmpv++)
{
LCDMEM[tmpv] = NUM_LCD[lcd_Buf[tmpv]]; //更新LCDMEM中的内容
}
}
/***********************************************************
*WDT中断服务程序
************************************************************/
interrupt[WDT_VECTOR] void watchdog_timer(void)
{
cont=cont+1;
if(cont==4)
{
cont=0;
y0=y0+1; //秒加1
s_num = (y0+7)/7; //以秒计数为敏感量
switch (s_num)
{
case 1: //高速正转
P1OUT = 0x40;
CCR1 = 511; //占空比 511/512≈1
break;
case 2: //次高速正转
P1OUT = 0x40;
CCR1 = 384; //占空比 384/512=0.75
break;
case 3: //中速正转
P1OUT = 0x40;
CCR1 = 256; //占空比 256/512=0.5
break;
case 4: //低速正转
P1OUT = 0x40;
CCR1 = 128; //占空比 128/512=0.25
break;
case 5: //高速反转
P1OUT = 0x80;
CCR1 = 511; //占空比 511/512≈1
break;
case 6: //次高速反转
P1OUT = 0x80;
CCR1 = 384; //占空比 384/512=0.75
break;
case 7: //中速反转
P1OUT = 0x80;
CCR1 = 256; //占空比 256/512=0.5
break;
case 8: //低速反转
P1OUT = 0x80;
CCR1 = 128; //占空比 128/512=0.25
break;
default : P1OUT = 0x00; //其余状态停转
break;
}
if(y0==60)
{
y0=0;
y1=y1+1; //60秒为1分,分加1
if(y1==60)
{
y1=0;
y2=y2+1; //60分为1小时,小时加1
if(y2==24)
{y2=0 ; //24小时再清零
}
}
}
cl_LCD();
lcd_Display();
_NOP();
}
}
/***********************************************************
*主程序
************************************************************/
void main(void)
{
WDTCTL = WDT_ADLY_250; // WDT间隔时间为250ms(ACLK)
IE1 |= WDTIE; // 使能WDT中断
SCFQCTL |= SCFQ_4M; // 设定主时钟为4MHz
init_LCD();
_EINT(); // 使能中断
cont=0;
y0=0;
y1=0;
y2=0;
P1DIR |= 0xC4; // P1.2 输出
P1SEL |= 0x04; // P1.2 TA1
TACTL = TASSEL0 + TACLR; // ACLK, 清除 TAR
CCR0 = 512-1; // PWM周期
CCTL1 = OUTMOD_7; // 设定输出模式7
CCR1 = 256; //占空比 256/512=0.5
TACTL |= MC0; // Timer_A 增计数模式
for (;;)
{
_BIS_SR(CPUOFF); //关CPU
_NOP(); // 调试程序使用
}
}
2)带调时按键的时钟与电机控制程序流程设计
程序流程框图如图5-8所示。
图5-8程序流程框图
2)程序设计
直流电机变速驱动小系统程序是在时钟小系统程序基础上增加了相应的初始化、按键读入、处理和电机驱动程序。程序清单如下:
#include <msp430x41x.h>
/*****************************************************
* 文件说明:时钟与直流电机控制程序
*****************************************************/
#define LCD_IN_USE 10
/******************************************************
* 数据定义七段译码表
*****************************************************/
const unsigned char NUM_LCD[17]={
0xd7, 0x06, 0xe3, 0xa7, 0x36, //'0'~ '4'
0xb5, 0xf5, 0x07, 0xf7, 0xb7, //'5' ~ '9'
0x77, 0xf4, 0xd1, 0xe6, 0xf1, // 'A'~ 'E'
0x71, 0x00}; // 'F','全熄'
unsigned char lcd_Buf[LCD_IN_USE]; // 自定义显示缓冲区,用于要显示的数据
unsigned int cont,y0,y1,y2,flag,flag1; //秒、时、分存储变量
/*******************************************************
* LCD模块初始化
*******************************************************/
void init_LCD(void)
{
char tmpv;
BTCTL = BT_fLCD_DIV32; // set LCD 时钟
P5SEL = 0xfc; // 置为外围模块
LCDCTL = LCDON+LCD4MUX+LCDP1; // 4Mux 模式
for (tmpv = 0;tmpv<10;tmpv++)
{
LCDMEM[tmpv] = 0x00; //clear LCD
}
}
/*******************************************************
* LCD清零模块
*******************************************************/
void cl_LCD(void)
{
char tmpv;
for (tmpv = 0;tmpv<10;tmpv++)
{
LCDMEM[tmpv] = 0x00; //clear LCD
}
}
/****************************************************
* 更新LCD缓冲区的内容,把数据显示到LCD
****************************************************/
void lcd_Display(void)
{
char tmpv;
lcd_Buf[0]=y2/10;
lcd_Buf[1]=y2%10;
lcd_Buf[2]=16;
lcd_Buf[3]=y1/10;
lcd_Buf[4]=y1%10;
lcd_Buf[5]=16;
lcd_Buf[6]=y0/10;
lcd_Buf[7]=y0%10;
lcd_Buf[8]=16;
lcd_Buf[9]=16;
for(tmpv=0;tmpv<LCD_IN_USE-1;tmpv++)
{
LCDMEM[tmpv] = NUM_LCD[lcd_Buf[tmpv]]; //更新LCDMEM中的内容
}
}
/***********************************************************
*时钟计数
************************************************************/
void shizhong(void)
{
cont=cont+1;
if(cont==4)
{
cont=0;
y0=y0+1; //秒加1
if(y0==60)
{
y0=0;
y1=y1+1; //60秒为1分,分加1
if(y1==60)
{
y1=0;
y2=y2+1; //60分为1小时,小时加1
if(y2==24)
{y2=0 ; //24小时再清零
}
}
}
cl_LCD();
lcd_Display();
_NOP();
}
}
/***********************************************************
*WDT中断服务程序
************************************************************/
interrupt[WDT_VECTOR] void watchdog_timer(void)
{
unsigned int snum,s_num;
snum = P6IN & 0x10; //P6.4 高(1)执行电机程序,低(0)执行时钟程序
if(snum==0)
{
P1OUT=0;
s_num = P6IN & 0x0F;
if(s_num!=0)
{
flag=1;
lcd_Display();
switch(s_num)
{
case 1: y0++; if(y0==60) y0=0; lcd_Display(); //调秒
break;
case 2: y1++; if(y1==60) y1=0; lcd_Display(); //调分
break;
case 4: y2++; if(y2==24) y2=0; lcd_Display(); //调时
break;
case 8: flag=0;
}
}
if(flag==0) shizhong();
}
else
{
shizhong();
s_num = P6IN & 0x0F;
if(s_num!=0)
{
switch(s_num)
{
case 1: flag1=1;
break;
case 2: flag1=2;
break;
case 4: flag1=4;
break;
case 8: flag1=8;
break;
}
}
switch(flag1)
{
case 0: P1OUT=0x7F; CCR1=255; break; //中速正转(默认状态)
case 1: P1OUT=0x7F; CCR1=511; break; //高速正转
case 2: P1OUT=0x7F; CCR1=100; break; //低速正转
case 4: P1OUT=0xBF; CCR1=100; break; //低速反转
case 8: P1OUT=0xBF; CCR1=511; break; //高速反转
}
}
}
/***********************************************************
*主程序
************************************************************/
void main(void)
{
WDTCTL = WDT_ADLY_250; // WDT间隔时间为250ms(ACLK)
IE1 |= WDTIE; // 使能WDT中断
SCFQCTL |= SCFQ_4M; // 设定TA时钟为4MHz
init_LCD();
P6DIR=0x0; //P6输入
P1DIR |= 0xC4; // P1.7\1.6\1.2输出
P1SEL |= 0x04; // P1.2 TA1
TACTL = TASSEL0 + TACLR; // ACLK, 清除 TAR
CCR0 = 512-1; // PWM周期
CCTL1 = OUTMOD_7; // 设定输出模式7
TACTL |= MC0; // Timer_A 增计数模式
_EINT(); // 使能中断
cont=0;
y0=0;
y1=0;
y2=0;
flag=0;
flag1=0;
for (;;)
{
_BIS_SR(CPUOFF); //关CPU
_NOP(); // C-spy使用
}
}
四、MSP430F413单片机为基的电动小车控制系统
1)电动小车结构
为了便于控制,电动小车采用三轮结构。由两直流电机分别驱动的主动轮在前,万向从动轮在后。左转时,左轮停、右轮向前转;右转时,右轮停、左轮向前转。
由于左、右电机和传动机构摩擦力不同,电动小车开始可能不走直线,调整左、右直流电机调速PWM信号占空比可消除这一现象。
2)电动小车电路设计
电动小车电路如图5-9所示。
3)程序设计提示
(1)在小时钟程序中加入5秒前进、5秒左转、5秒右转、5秒后退和10秒停车控制程序。
(2)在小时钟程序中加入5秒低速前进、5秒中速前进、5秒高速前进;5秒低速左转、5秒中速左转、5秒高速左转;5秒低速右转、5秒中速右转、5秒高速右转;5秒低速后退、5秒中速后退、5秒高速后退控制程序。
图5-9 电动小车电路图
今天分享一个MSP430非常好的教材,是南韩的老师上课用的教材,内容很丰富,而且是针对培训新手的,所以非常适合初学者啦!
对我主要的帮助就是,非常适合初学,而且这本教材是用一个一个的实验来让你一步一步的了解MSP430,所以,非常的通俗易懂。
通过 MSP430 进行 PCB 电容触摸感应
电容触摸是430的一大特色,本文从硬件和软件多个方面介绍了如何利用430来设计电容触摸传感器。本文还特别介绍了设计中的一些注意事项,看后收获很大,对设计很有用。
刚学习430一个月,有这个活动真给力!希望能在此活动能获得更多的知识。
下面是我写的一个430的频率计,新手入门,大家见谅。
/**********************************************************
说 明:MSP430F168频率计
软 件:编程软件IAR
功 能:TB用于外部计数,计频率; TA用于闸门控制
P4.7为被测频率输入口
**********************************************************/
#include <stdio.h>
#include <msp430x16x.h>
#include "12864.h"
unsigned char cnt50ms =0, gate_1s =0, flag=0,tb1=0;
unsigned long freq0,freq1;
float freq;
unsigned char dis_Fre[1];
void CLK_Init(void);
void TIMERA_B_Init(void);
void Basicdisplay(void);
void main()
{
WDTCTL = WDTPW + WDTHOLD; // 关闭开门狗
CLK_Init(); //系统时钟初始化
TIMERA_B_Init(); //定时器A,B初始化
_EINT(); //通用中断允许
Init_LCD12864();
delay_Nms(100);
while(1)
{
if(flag==1)
{
freq =65536*freq1 +freq0;
flag=0;
}
Basicdisplay();
}
}
/*******************************************
函数名称:Basicdisplay
功 能:基本信息显示函数
参 数:无
返回值 :无
********************************************/
void Basicdisplay(void)
{
// sendcm(0x82);
// display_12864(" ");
sendcm(0x80);
display_12864("Fre:");
sprintf(dis_Fre,"%.f",freq);
display_12864(dis_Fre);
display_12864("Hz ");
// delay_Nms(1800);
}
/*******************************************
函数名称:CLK_Init
功 能:系统时钟初始化
参 数:无
返回值 :无
********************************************/
void CLK_Init(void)
{
BCSCTL1&=~XT2OFF; // BCSCTL1 基本时钟系统控制寄存器1,XT2OFF 控制XT2振荡器的开启与关闭,0为XT2振荡器开启。
BCSCTL2|=SELM_2+SELS;// BCSCTL2 基本时钟系统控制寄存器2 ,选择时钟源MCLK 8M and SMCLK 8M
do
{
IFG1 &= ~OFIFG; // 清除振荡错误标志
delay_Nus(100); // 延时等待
}
while ((IFG1 & OFIFG) != 0); // 如果标志为1继续循环等待 , 如果OSCFault =1
IFG1&=~OFIFG;
}
/*******************************************
函数名称:TIMERA_B_Init
功 能:定时器A,B初始化
参 数:无
返回值 :无
********************************************/
void TIMERA_B_Init(void)
{
TACTL =TASSEL_2 +ID_3 +MC_1 +TACLR; // SMCLK, 1/8->1MHz--1us, UPCOUNT, CLEAR
CCTL0=CCIE; // enable CCR0
CCR0=49999; // 50000*1us*0.001=50mS
TBCTL =TBSSEL_0 +MC_2 +TBCLR; // TBCLK, UPMAX, CLR
TBCTL |=TBIE;
P4SEL |=BIT7; // SECOND FUNCTION
P4DIR &=~BIT7; // 设置P4.7为输入
}
#pragma vector=TIMERA0_VECTOR
__interrupt void TIMERA_ISR()
{
cnt50ms++;
if(cnt50ms==20) //20个50ms,合计1S,闸门时间
{
TBCTL &=~(MC1+MC0); // 定时器B停止计数
TACTL &=~(MC1+MC0); // STOP counter
cnt50ms=0; // gate_1s =~gate_1s;
freq0 =TBR; // get data
freq1 =tb1;
TBR=0; // clear
tb1=0;
flag=1;
TBCTL |=MC_2;
TACTL |=MC_1; // open counter
}
}
#pragma vector=TIMERB1_VECTOR // TBCCR0-->TIMERB0_VECTOR
__interrupt void TIMERB_ISR()
{
tb1++;
switch(TBIV)
{
case 10: break;
}
}
难得有这么个机会,希望我能得到一块430的开发板,以得到更好的学习机会!
这是我在搜索资料中找到的一个链接,分享给大家一起学习:http://shop.21ic.com/brand.php?id=68&page=2&sort=goods_id&order=DESC
我在学习的开始,是从一本写有关于430寄存器的一书开始,觉得很有用,大家一起学习
1.2 在声明结构体的同时定义变量:
1.3 使用 typedef 来简化struct的类型说明:
1.4 使用时尤其注意后面的分号,必不可少;
二. struct 与 union的区别
2.1 struct中的成员是按顺序依次排列,互相独立,在排列时引入了对齐问题(2.2);而union中的成员共用一块内存,起始地址都是相同的,即union中的成员是对同一地址的多个引用、对同一地址的多种表达方法。
2.2 struct的对齐问题
对齐问题即struct中每个成员起始地址的分配。为了可以快速访问到每个成员,(以EW430为例)编译器根据成员的类型放到合适的地址上,默认为2字节对齐。如:
Struct AA{char c; int d;}aa;
假设aa被分配在地址N上,并且N为偶数,则aa.c的地址为N,aa.d的地址为N+2,而N+1地址未使用被浪费了。
对齐字节大小的指定:通过#pragma pack(n)来指定对齐字节的大小,n为某些常量(EW430中可取1,2,4,8,16),指定以n字节对齐。通常使用编译器默认的对齐大小最为适宜。如果指定对齐大小为1字节对齐,以上面的结构体变量aa为例,aa.c地址为N,aa.d地址为N+1,是个奇数地址,因为430在奇数地址只能读取一个字节,因此要访问d成员需要读取两次才能完成,后果是代码变长、速度变慢。
三. 匿名结构体与联合体
匿名结构体和联合体,即没有名字的结构体或者联合体,这种结构体(或联合体)无法通过.与->操作符引用(因为它所属的结构体或联合体没有名字,无法应用),而像暴露在外面一样,与外层作用域相同,可直接使用。
3.1 C标准中提及的匿名结构体和联合体(草稿原文引用)(C标准中提及的匿名结构(联合)体应该只适用于有名结构体(联合)中的匿名结构(联合)体成员)
3.2 IAR中的匿名结构体和联合体
IAR中的匿名结构体和联合体可以具有全局作用域,因此结构体或联合体中的成员可以作为全局变量使用,但却兼具结构体或者联合体的属性。
(1) IO430.h系列头文件的寄存器声明方式:
如:
说明:[1]. SFRIE1和SFRIE1_bit具有全局变量的性质,可以直接被引用。
[2]. SFRIE1和SFRIE1_bit在同一联合体中,根据联合体的性质,他们共享同一地址,即对同一寄存器不同访问方式,SFRIE1对整个寄存器操作,SFRIE1_bit可对某位操作,如:
SFRIE1 |= 0x0001;和SFRIE1_bit.WDTIE = 1;具有相同效果。
[3]. 冒号(:)与整数称之为位域,使用位域表达的变量使用同一数据中的不同位,并按顺序排列。整数表示这个变量占用多少位。没有名字的位域不能被引用到,一般用来保留未使用到的位(占位作用)。
(2) 在应用程序中也可以使用此特性来实现一些功能。
记得某位网友曾提出过这样的问题,要高效的使用一个整数的高8位和低8位,则可以用如下代码解决:
或者
非常好的解决方案,只占用一个整数的空间,可以对高8位、低8位、整个16位引用而不需要计算。
(3) 联合体中的位域(补充)
结果:a = 1, b = 3, c = 7;
(4)结构体中的位域长度0 (补充)
长度为0的位域是通知编译器不要在以前的单元上分配位域了,代表着一个单元的位域分配结束,这个长度为0的位域不能有名字。以后的位域分配要新开辟一个单元。
以上的例子中,z1, z2, z3, z4共用一个unsigned int中的4个bit,z6单独使用一个unsigned int; 此结构体共占用两个unsigned int空间
1.2 在声明结构体的同时定义变量:
1.3 使用 typedef 来简化struct的类型说明:
1.4 使用时尤其注意后面的分号,必不可少;
二. struct 与 union的区别
2.1 struct中的成员是按顺序依次排列,互相独立,在排列时引入了对齐问题(2.2);而union中的成员共用一块内存,起始地址都是相同的,即union中的成员是对同一地址的多个引用、对同一地址的多种表达方法。
2.2 struct的对齐问题
对齐问题即struct中每个成员起始地址的分配。为了可以快速访问到每个成员,(以EW430为例)编译器根据成员的类型放到合适的地址上,默认为2字节对齐。如:
Struct AA{char c; int d;}aa;
假设aa被分配在地址N上,并且N为偶数,则aa.c的地址为N,aa.d的地址为N+2,而N+1地址未使用被浪费了。
对齐字节大小的指定:通过#pragma pack(n)来指定对齐字节的大小,n为某些常量(EW430中可取1,2,4,8,16),指定以n字节对齐。通常使用编译器默认的对齐大小最为适宜。如果指定对齐大小为1字节对齐,以上面的结构体变量aa为例,aa.c地址为N,aa.d地址为N+1,是个奇数地址,因为430在奇数地址只能读取一个字节,因此要访问d成员需要读取两次才能完成,后果是代码变长、速度变慢。
三. 匿名结构体与联合体
匿名结构体和联合体,即没有名字的结构体或者联合体,这种结构体(或联合体)无法通过.与->操作符引用(因为它所属的结构体或联合体没有名字,无法应用),而像暴露在外面一样,与外层作用域相同,可直接使用。
3.1 C标准中提及的匿名结构体和联合体(草稿原文引用)(C标准中提及的匿名结构(联合)体应该只适用于有名结构体(联合)中的匿名结构(联合)体成员)
3.2 IAR中的匿名结构体和联合体
IAR中的匿名结构体和联合体可以具有全局作用域,因此结构体或联合体中的成员可以作为全局变量使用,但却兼具结构体或者联合体的属性。
(1) IO430.h系列头文件的寄存器声明方式:
如:
说明:[1]. SFRIE1和SFRIE1_bit具有全局变量的性质,可以直接被引用。
[2]. SFRIE1和SFRIE1_bit在同一联合体中,根据联合体的性质,他们共享同一地址,即对同一寄存器不同访问方式,SFRIE1对整个寄存器操作,SFRIE1_bit可对某位操作,如:
SFRIE1 |= 0x0001;和SFRIE1_bit.WDTIE = 1;具有相同效果。
[3]. 冒号(:)与整数称之为位域,使用位域表达的变量使用同一数据中的不同位,并按顺序排列。整数表示这个变量占用多少位。没有名字的位域不能被引用到,一般用来保留未使用到的位(占位作用)。
(2) 在应用程序中也可以使用此特性来实现一些功能。
记得某位网友曾提出过这样的问题,要高效的使用一个整数的高8位和低8位,则可以用如下代码解决:
或者
非常好的解决方案,只占用一个整数的空间,可以对高8位、低8位、整个16位引用而不需要计算。
(3) 联合体中的位域(补充)
结果:a = 1, b = 3, c = 7;
(4)结构体中的位域长度0 (补充)
长度为0的位域是通知编译器不要在以前的单元上分配位域了,代表着一个单元的位域分配结束,这个长度为0的位域不能有名字。以后的位域分配要新开辟一个单元。
以上的例子中,z1, z2, z3, z4共用一个unsigned int中的4个bit,z6单独使用一个unsigned int; 此结构体共占用两个unsigned int空间
一直想用430单片机做一些电子DIY,但限于430单片机贴片的封装形式,焊接起来实在很不方便,只好作罢,于是只好使用STC系列的直插封装的单片机。最近在做低功耗压力检测系统检测方面的工作,于是又再一次想起了430单片机。
我觉得学习单片机做好的资料,最好的资料就是芯片数据手册了。在这里分享一个我当时学习430单片机时找到的的一篇中文的430单片机数据手册,个人觉得还不错。