为什么32单片机上传数据给微机给PWM

还没有帐号? 赶紧
用户版块帖子
STM32输出PWM如何提高精度?
UID:824903
在线时间319小时
M币3133专家4
STM32输出的PWM,受输入电压3.3V的影响,会有波动,如何使输出的PWM稳定一些?3.3V 的稳压受温度影响,波动很大,直接影响输出的PWM。有什么好的方法吗
UID:824903
在线时间319小时
M币3133专家4
谁有便宜的稳定的DAC芯片推荐也可以
UID:1351094
在线时间118小时
M币1175专家6
PWM不会受影响。但是你如果用PWM去滤波获得直流电压,肯定会受电源影响的,解决办法就是换基准源
UID:1038188
在线时间1548小时
M币9620专家98
用PWM对基准源斩波。
UID:1108815
在线时间1300小时
M币1126专家3
用PWM做DAC,电源有波动,又不想增加额外的硬件,可以尝试先用单片机的ADC对电源菜样,然后用算法补偿到PWM,就可以得到相对稳定的DAC输出
UID:1351094
在线时间118小时
M币1175专家6
回 xpicompany 的帖子
:用PWM做DAC,电源有波动,又不想增加额外的硬件,可以尝试先用单片机的ADC对电源菜样,然后用算法补偿到PWM,就可以得到相对稳定的DAC输出 ( 19:25) 没用。两者都共用一个“基准源”,也就是供电的3.3V
UID:1108815
在线时间1300小时
M币1126专家3
回 amo73 的帖子
:没用。两者都共用一个“基准源”,也就是供电的3.3V ( 20:18) STM32是有1.2V的内部参照电压的啊
UID:824903
在线时间319小时
M币3133专家4
回 amo73 的帖子
:PWM不会受影响。但是你如果用PWM去滤波获得直流电压,肯定会受电源影响的,解决办法就是换基准源 ( 18:38) 64脚的,没有外接基准,用的就的电源电压有好办法弄一个高精度的电压源来供电也可以,关键是怎么做
UID:824903
在线时间319小时
M币3133专家4
回 amo73 的帖子
:没用。两者都共用一个“基准源”,也就是供电的3.3V ( 20:18) 我用 的是64脚的芯片,换成100脚的,外接基准源可以吧,有人说外界基准对PWM无效,只针对ADC,不知道真假
UID:1173863
在线时间971小时
M币2809专家4
ADC闭环调节,或加mos管对另一个独立的电压pwm斩波没试过,瞎想的
访问内容超出本站范围,不能确定是否安全
“新手上路”发帖需审核后才能显示(请认真发帖),达到数码9级后取消此限制
您目前还是游客,请
&回复后跳转到最后一页
Code by , Time now is:01-08 18:31, Total 0.163270(s) query 9,
Gzip enabled&STM32单片机学习---PWM输出
上午花了半天时间熟悉了stm32的PWM模块。中午利用午饭时间把PWM功能调试成功。当然,很简单的东西,也许很多前辈估计都不屑一顾的东西。
今天最大的感叹就是网络资源实在是个巨大的宝库,真的很庆幸,在这个复杂的社会环境里,在一个到处充斥着私心、私利的时代,各个网站,各个论坛上的众多网友都时刻保持着开源的氛围。学习一定要和他人交流,而网络提供了这么一个极好的平台。
废话少说,言归正传。
实现功能:采用定时器2的通道2,使PA1输出频率1K,占空比40的PWM波形,用PA8随意延时取反led灯,指示程序运行。
首先熟悉一下定时器的PWM相关部分。看图最明白
其实PWM就是定时器的一个比较功能而已。
CNT里的值不断++,一旦加到与CCRX寄存器值相等,那么就产生相应的动作。这点和AVR单片机很类似。既然这样,我们要产生需要的PWM信号,就需要设定PWM的频率和PWM的占空比。
首先说频率的确定。由于通用定时器的时钟来源是PCLK1,而我又喜欢用固件库的默认设置,那么定时器的时钟频率就这样来确定了,如下:
AHB(72MHz)→APB1分频器(默认2)→APB1时钟信号(36MHz)→倍频器(*2倍)→通用定时器时钟信号(72MHz)。
这里为什么是这样,在RCC模块学习记录里有详细记载,不多说。
因此图中的CK_PSC就是72MHz了。
下面的资料也是网上一搜一大把,我就罗列了:
STM32的PWM输出有两种模式,模式1(PWM1)和模式2(PWM2),由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下:
110:PWM模式1-在向上计数时,一旦TIMx_CNT=TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
111:PWM模式2-在向上计数时,一旦TIMx_CNT=TIMx_CCR1时通道1为有效电平,否则为无效电平。
由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。我用的是模式一,因此后面的设定都是按照模式一来设定的。
PWM的周期是就是由定时器的自动重装值和CNT计数频率决定的。而CNT的计数时钟是CK_PSC经分频器PSC得到,因此CNT的时钟就是CK_PSC/分频系数。这个分频系数在TIM_TimeBaseStructure.TIM_Prescaler确定。我设置的值是72,因此CNT的计数频率也就是CK_CNT的频率为1MHz。
下一步就是确定定时器自动重装值。因为CNT每自加到ARR寄存器的值时就会自动清零,当然前提是设定为为向上计数模式,而就是根据这个溢出事件来改变PWM的周期。所以PWM信号的频率由ARR的值来确定。我设置的值是1000-1,即TIM_TimeBaseStructure.TIM_Period
= 1000-1;因此PWM的周期是1MHz/1000=1KHz。
接下来就要确定PWM的占空比了。因为CNT在自加到ARR值的过程中会不断和CRRX的值相比较,一旦二者相等就产生匹配事件,但要注意CNT不会理会这件事,它会继续++直到等于ARR。而CRRX的值我设定为400-1,那么占空比就随之确定为40%。
好了,下面就是库函数的配置了。
TIMER输出PWM实现步骤
设置RCC时钟;
设置GPIO;
设置TIMx定时器的相关寄存器;
设置TIMx定时器的PWM相关寄存器。
首先是main函数和全局变量申明,很简单,不作说明
GPIO_InitTypeDef GPIO_InitS
TIM_TimeBaseInitTypeDef TIM_TimeBaseS
TIM_OCInitTypeDef TimOCInitS
int main(void)
rcc_cfg();
gpio_cfg();
tim2_cfg();
pwm_cfg();
& while (1)
GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);
GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);
下面是IO口的配置:
void gpio_cfg()
& RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,
& GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;
& GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
& GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_Out_PP;
& GPIO_Init(GPIOA, &GPIO_InitStructure);
& GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;
& GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
& GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_AF_PP;
& GPIO_Init(GPIOA, &GPIO_InitStructure);
此处要注意的是PWM输出口要配置为复用推挽输出,原因我也不知道,反正照搬就是了。
下面是TIM配置函数,注释很清楚了,不作说明:
void tim2_cfg()
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
& TIM_DeInit(TIM2);
& TIM_InternalClockConfig(TIM2);
& //预分频系数为72,这样计数器时钟为72MHz/72 = 1MHz
& TIM_TimeBaseStructure.TIM_Prescaler = 72;
& //设置时钟分割
& TIM_TimeBaseStructure.TIM_ClockDivision =
TIM_CKD_DIV1;
& //设置计数器模式为向上计数模式
& TIM_TimeBaseStructure.TIM_CounterMode =
TIM_CounterMode_Up;
& //设置计数溢出大小,每计1000个数就产生一个更新事件
& TIM_TimeBaseStructure.TIM_Period = 1000-1;
& //将配置应用到TIM2中
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
& //禁止ARR预装载缓冲器
& TIM_ARRPreloadConfig(TIM2, DISABLE);
& TIM_Cmd(TIM2, ENABLE);&
//使能TIMx外设
接下来是关键的PWM的配置函数:
void pwm_cfg()
//设置缺省值
TIM_OCStructInit(&TimOCInitStructure);
//PWM模式1输出
TimOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//设置占空比,占空比=(CCRx/ARR)*100%或(TIM_Pulse/TIM_Period)*100%
TimOCInitStructure.TIM_Pulse = 400-1;
//TIM输出比较极性高
TimOCInitStructure.TIM_OCPolarity =
TIM_OCPolarity_H
//使能输出状态
TimOCInitStructure.TIM_OutputState =
TIM_OutputState_E
//TIM2的CH2输出
TIM_OC2Init(TIM2,
&TimOCInitStructure);
//设置TIM2的PWM输出为使能
TIM_CtrlPWMOutputs(TIM2,ENABLE);
stm32固件库的输出比较单元结构体与定时器的时基单元是分开定义的,而PWM模式只是输出比较结构体成员TimOCInitStructure.TIM_OCMode的一个取值,当把此结构体填充完后,还要映射到某个定时器,用TIM_OCXInit函数实现,我用了一个X,说明不止一个这样的函数,事实上,stm32的通用定时器都有四个通道,每个通道对应一个初始化函数,这里真够纠结的!最后还要使能该定时器的PWM输出功能,TIM_CtrlPWMOutputs(TIM2,ENABLE)函数要注意,是outputs而不是output,说明TIM2不止一个通道嘛!够复杂,够繁琐的!
下面是输出比较单元的结构体原型:
typedef struct
& uint16_t
TIM_OCM&&&&&&&
& uint16_t
TIM_OutputState;&&
& uint16_t
TIM_OutputNS&
& uint16_t
TIM_Pulse;&&&&&&&&
& uint16_t
TIM_OCPolarity;&&&
& uint16_t
TIM_OCNP&&
& uint16_t
TIM_OCIdleS&&
& uint16_t
TIM_OCNIdleS&
} TIM_OCInitTypeD
其中没有加色的成员是高级定时器才有的,通用定时器就不用管了。
这里还有个TimOCInitStructure.TIM_OCPolarity 成员需要注意,它有什么作用呢?在网上查的资料,如下图:
前面说到pwm有pwm1和pwm2两种模式,这两种模式只能控制到OCXREF为止,TIM_OCPolarity
能控制OC1是直接等于OCXREF,还是取反极性!OC1才是最终的PWM信号。
这里有个小插曲,我用示波器去测量PWM信号,发现信号居然是双极性的,然后改变TIM_OCPolarity
,再测,还是双极性,只是倒了个跟头。还真以为stm32单片机能输出两极性的PWM,后面把示波器改为直流档(之前用的是交流档),波形才从零电位一下纵向移上去。以后要注意!
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。查看: 385|回复: 18
PWM用硬件怎么实现,求教各位大神!
PWM用硬件怎么实现,求教各位大神!
有的单片机有专门的陪我们、
开一个定时器计数,设置一个比较值,定义一个io口输出pwm,当定时器计数值大于比较值输出一个电平,else输出另一个电平。
回帖助人的奖励!
滞回比较器&&你试试
回帖助人的奖励!
用锯齿波发生器和比较器一起来用就可以了。
回帖助人的奖励!
LM358 可以实现PWM.
回帖助人的奖励!
555占空比实验
555就可以实现
回帖助人的奖励!
有单片机自带pwm通道,也有fpga来实现,都算硬件的
回帖助人的奖励!
有点怀疑你是不是问错了问题,你是说用硬件实现,那和单片机无关了哦。
494,3842都可以。便宜、电路简单、可控可调。
回帖助人的奖励!
用555定时芯片就可以。
无效楼层,该帖已经被删除
SG3525,可实现,PWM占空比可调,频率也可以设置,纯硬件完成
去网上找一个H桥电路就可以了
你应该说一下你用的单片机型号是什么。增强型51单片机硬件支持PWM,频率可调,占空比可调,STM32的单片机也有,功能也很强大。如果你想搭个电路实现,楼上很多朋友已经有解释了。
用TL494芯片可以实现,直接在网上百度TL494产生PWM波的图
这个要用555数字芯片定时器吧
Powered by(急)单片机如何产生PWM信号的?_百度知道
(急)单片机如何产生PWM信号的?
1、用普通I/O口采用软件定时器中断可以模拟PWM输出。&/**/&里面的内用是对程序的标注,解析。2、/*采用6MHz晶振,在P1.0脚上输出周期为2.5s,占空比为20%的脉冲信号*/ /*定时100ms,周期2.5s需25次中断,高电平0.5s需5次中断*/ #include &reg51.h& typedef sbit P1_0=P1^0; uchar time=0; uchar period=25; uchar high=5; void timer0() interrupt 1 using 1 { TH0=0x3c; /*定时器初值重装载*/ TL0=0xb0; time++; if(time==high) /*高电平持续时间结束,变低*/ { P1_0=0;} else if(time==period) /*周期时间到,变高*/ { time=0; P1_0=1; } } void main() { TMOD=0x01; /*定时器0方式1*/ TH0=0x3c; /*定时器装载初值*/ TL0=0xb0; EA=1; /*开CPU中断*/ ET0=1; /*开定时器0中断*/ TR0=1;/*启动定时器0*/ while(1) /*等待中断*/ {} }
采纳率:83%
来自团队:
上面都写着的可以进入 www.dzsc
本回答被提问者采纳
使用ADUC842,51内核,即可产生PWM
为您推荐:
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。跪求大神怎么让MC9S08AW32芯片PWM脚输出电压为0~5V【单片机吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:144,574贴子:
跪求大神怎么让MC9S08AW32芯片PWM脚输出电压为0~5V收藏
帮个忙解决,加qq,学生一枚,适当给个红包,求帮忙~~~
单片机开发专业PCB设计,制板,贴片打样一站式服务!软硬件相结合,打造整体产品解决方案提供商.
#include &hidef.h& /* for EnableInterrupts macro */#include &MC9S08AW32.h& /* include peripheral declarations */#include &cnxdef.h&#include &cnxsci.h&#include &cnxcest.h&#include &dmxpwm.h&void Device_ID(void) ;void Init_TPM2(void) ;void Init_RTI(void);//==============================================================//变量声明//===============================================================#pragma DATA_SEG _DATA_ZEROPAGEvolatile unsigned int D//PWM脉冲宽度变量分配内存volatile unsigned int
//PWM周期volatile unsigned char SCIRecB//SCI接收缓存单元volatile//通道调光数据volatile unsigned char CresRec1;//Cres协议记录的第1字节缓存volatile unsigned char CresRec2;volatile unsigned char CresRec3;volatile unsigned char CresRec4;volatile unsigned char CresRec5;volatile FlagCellSTR _FlagC //协议记录字节缓存存在数据标志volatile AnotFlagSTR _AnotF //是否允许应答响应volatile unsigned char Rvolatile unsigned char TPM2counter=0;//定时器2计数器volatile unsigned char ID;volatile unsigned char MachInf[4]; //存设备信息号//==============================================================//调光主程序//===============================================================void main(void) {
ICGC1 = 0x78;
ICGC2 = 0x30;
//外部晶振4MHz,总线频率20MHz
__RESET_WATCHDOG();#ifdef DEBUG
SOPT_COPE = 0;
while(!ICGS1_LOCK); #else
while(!ICGS1_LOCK)
__RESET_WATCHDOG(); #endif
PTADD = 0x03;
PTAD = 0x01;//禁止485使能引脚
PTBDD=0x00;
PTBPE =0 //上拉使能
PTDDD=0x00;
PTGDD_PTGDD0=1; //输出
PTGD_PTGD0=1; //初始化信号灯LED1灭
PTGDD_PTGDD1=1; //输出
PTGD_PTGD1=1; //初始化信号灯LED2灭PTGDD_PTGDD0
/* include your code here */ID=0x31;MachInf[0]=0MachInf[1]=0x00;MachInf[2]=ID;MachInf[3]=0
FlagCell=0;//变量初始化
AnotFlag=0; //变量初始化
Period =PWMP//变量初始化
AnotFlag_Temptyp=1;
SCI1_init();//串口1初始化程序
Init_TPM2();//定时器2初始化
PWMInit(Period);//PWM初始化
Init_RTI();
TPM1SC = TPM1SC | TPM1SC_CLKSA_MASK;/* Turn on timer1*/
TPM2SC = TPM2SC | TPM2SC_CLKSA_MASK;/* Turn on timer1*/
EnableI /* enable interrupts */
__RESET_WATCHDOG();
TPM1C1V = 0
// PTGD_PTGD1 = 0;
//-------------
Device_ID() ; //获取设备的实时ID号
CresAgrSub();//执行协议子程序
if(AnotFlag_TempAns) //连通ANET,LED2亮
PTGD_PTGD1=0;
if(AnotFlag_Temptyp)//ANET连通标志灯点亮延时完毕后开通下一次计时
AnotFlag_Temptyp=0;
SRTISC_RTIE=1;
__RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */
/* please make sure that you never leave this function */}//--------------------------------------------------------------------------------////----------------------获取设备ID号函数--------------------------------------------////--------------------------------------------------------------------------------//void Device_ID(void) { unsigned char temp1,temp2;
temp1 = PTBD;
temp1 &= (0xf);
temp1 = temp1&&4;
temp2 = PTDD;
temp2 &= (0xf);
ID = temp1|temp2;
ID=~ID; //获取旋转编码器设置的ID号}//--------------------------------------------------------------------------------////-------------------初始化定时器2程序--------------------------------------------////--------------------------------------------------------------------------------//void Init_TPM2(void) //定时375us{
TPM2SC=0x0a; //总线时钟,4分频
TPM2MODH=0x07;
TPM2MODL=0x53;
TPM2CNT=0;}//--------------------------------------------------------------------------------////-------------------定时器2溢出中断服务程序--------------------------------------////--------------------------------------------------------------------------------//interrupt 14 void TPM2_OVF(void) {if((TPM2SC & 0x80)==0x80) {
TPM2SC_TOF=0;
TPM2CNT=0;TPM2MODH=0x07; //定375-400us
TPM2MODL=0x53;
TPM2counter++;
if(TPM2counter==26)//100ms
TPM2counter=0;
TPM2SC_TOIE=0;
PTGD_PTGD0=1; //信号灯LED1灭
}} __RESET_WATCHDOG(); }//=================================//函数名:RTI初始化//=================================void Init_RTI(void){SRTISC=0x07;//中断使能,时间间隔1.02S;}//=================================//函数名:RTI中断服务函数//=================================interrupt 25 void RTI_ISR(void){if((SRTISC&0x80)==0x80) {
AnotFlag_Temptyp=1;//ANET连通信号灯点亮延时1.02s完毕标志 SRTISC_RTIACK=1;
SRTISC_RTIE=0; if(AnotFlag_TempAns) //连通ANET,LED2亮
PTGD_PTGD1=0;
PTGD_PTGD1=1;
#include &hidef.h& /* for EnableInterrupts macro */#include &MC9S08AW32.h& /* include peripheral declarations */#include &cnxdef.h&#include &cnxsci.h&#include &cnxcest.h&#include &dmxpwm.h&void Device_ID(void) ;void Init_TPM2(void) ;void Init_RTI(void);//==============================================================//变量声明//===============================================================#pragma DATA_SEG _DATA_ZEROPAGEvolatile unsigned int D//PWM脉冲宽度变量分配内存volatile unsigned int
//PWM周期volatile unsigned char SCIRecB//SCI接收缓存单元volatile//通道调光数据volatile unsigned char CresRec1;//Cres协议记录的第1字节缓存volatile unsigned char CresRec2;volatile unsigned char CresRec3;volatile unsigned char CresRec4;volatile unsigned char CresRec5;volatile FlagCellSTR _FlagC //协议记录字节缓存存在数据标志volatile AnotFlagSTR _AnotF //是否允许应答响应volatile unsigned char Rvolatile unsigned char TPM2counter=0;//定时器2计数器volatile unsigned char ID;volatile unsigned char MachInf[4]; //存设备信息号//==============================================================//调光主程序//===============================================================void main(void) {
ICGC1 = 0x78;
ICGC2 = 0x30;
//外部晶振4MHz,总线频率20MHz
__RESET_WATCHDOG();#ifdef DEBUG
SOPT_COPE = 0;
while(!ICGS1_LOCK); #else
while(!ICGS1_LOCK)
__RESET_WATCHDOG(); #endif
PTADD = 0x03;
PTAD = 0x01;//禁止485使能引脚
PTBDD=0x00;
PTBPE =0 //上拉使能
PTDDD=0x00;
PTGDD_PTGDD0=1; //输出
PTGD_PTGD0=1; //初始化信号灯LED1灭
PTGDD_PTGDD1=1; //输出
PTGD_PTGD1=1; //初始化信号灯LED2灭PTGDD_PTGDD0
/* include your code here */ID=0x31;MachInf[0]=0MachInf[1]=0x00;MachInf[2]=ID;MachInf[3]=0
FlagCell=0;//变量初始化
AnotFlag=0; //变量初始化
Period =PWMP//变量初始化
AnotFlag_Temptyp=1;
SCI1_init();//串口1初始化程序
Init_TPM2();//定时器2初始化
PWMInit(Period);//PWM初始化
Init_RTI();
TPM1SC = TPM1SC | TPM1SC_CLKSA_MASK;/* Turn on timer1*/
TPM2SC = TPM2SC | TPM2SC_CLKSA_MASK;/* Turn on timer1*/
EnableI /* enable interrupts */
__RESET_WATCHDOG();
TPM1C1V = 0
// PTGD_PTGD1 = 0;
//-------------
Device_ID() ; //获取设备的实时ID号
CresAgrSub();//执行协议子程序
if(AnotFlag_TempAns) //连通ANET,LED2亮
PTGD_PTGD1=0;
if(AnotFlag_Temptyp)//ANET连通标志灯点亮延时完毕后开通下一次计时
AnotFlag_Temptyp=0;
SRTISC_RTIE=1;
__RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */
/* please make sure that you never leave this function */}//--------------------------------------------------------------------------------////----------------------获取设备ID号函数--------------------------------------------////--------------------------------------------------------------------------------//void Device_ID(void) { unsigned char temp1,temp2;
temp1 = PTBD;
temp1 &= (0xf);
temp1 = temp1&&4;
temp2 = PTDD;
temp2 &= (0xf);
ID = temp1|temp2;
ID=~ID; //获取旋转编码器设置的ID号}//--------------------------------------------------------------------------------////-------------------初始化定时器2程序--------------------------------------------////--------------------------------------------------------------------------------//void Init_TPM2(void) //定时375us{
TPM2SC=0x0a; //总线时钟,4分频
TPM2MODH=0x07;
TPM2MODL=0x53;
TPM2CNT=0;}//--------------------------------------------------------------------------------////-------------------定时器2溢出中断服务程序--------------------------------------////--------------------------------------------------------------------------------//interrupt 14 void TPM2_OVF(void) {if((TPM2SC & 0x80)==0x80) {
TPM2SC_TOF=0;
TPM2CNT=0;TPM2MODH=0x07; //定375-400us
TPM2MODL=0x53;
TPM2counter++;
if(TPM2counter==26)//100ms
TPM2counter=0;
TPM2SC_TOIE=0;
PTGD_PTGD0=1; //信号灯LED1灭
}} __RESET_WATCHDOG(); }//=================================//函数名:RTI初始化//=================================void Init_RTI(void){SRTISC=0x07;//中断使能,时间间隔1.02S;}//=================================//函数名:RTI中断服务函数//=================================interrupt 25 void RTI_ISR(void){if((SRTISC&0x80)==0x80) {
AnotFlag_Temptyp=1;//ANET连通信号灯点亮延时1.02s完毕标志 SRTISC_RTIACK=1;
SRTISC_RTIE=0; if(AnotFlag_TempAns) //连通ANET,LED2亮
PTGD_PTGD1=0;
PTGD_PTGD1=1;
#include &MC9S08AW32.h& /* include peripheral declarations */#include &cnxdef.h&#include &cnxsci.h&#include &cnxcest.h&#include &dmxpwm.h&//=================================================//串口1初始化设置//=================================================void SCI1_init(void) {
SCI1BD = 0x0021;
//baud rate 38400 at 20MHz
SCI1C1_M=1;
SCI1C2_TE = 1;//0:禁止发送;1:使能发送//SCI1C2_TIE = 0;//0:禁止发送中断;1:使能发送中断//SCI1C2_TCIE = 0;SCI1C3_T8 = 1;//发送数据校验位为MARK
//SCI1C2_RIE = 0;
//0:禁止接收中断;1:使能接收中断SCI1C2_RE = 1;
//开SCI接收__RESET_WATCHDOG();}//=================================================//串口2初始化设置//=================================================/*void SCI2_init(void) {
SCI2BD = 0x0021;
//baud rate 38400 at 20MHz
SCI2BD = 0x0011;
//baud rate 38400 at 20MHz
SCI2C2_TE = 0;//0:禁止发送;1:使能发送SCI2C2_TIE = 0;//0:禁止发送中断;1:使能发送中断SCI2C2_TCIE = 0;
SCI2C2_RIE = 1;
//0:禁止接收中断;1:使能接收中断SCI2C2_RE = 1;
//禁止SCI接收
SCI2BD = 0x0011;
baud rate 38400 at 4.9152*4 MHz
= 0;//在执行Smart协议时收发每字节为8位 //
SCI2C2_RE = 0;//禁止SCI接收 //
SCI2C2_TE = 1;//0:禁止发送;1:使能发送
} *///====================================================//SCI2接收中断服务程序//==================================================== /*interrupt 20 void SCI2_RX_ISR(void){
unsigned int dummy = 0;
if ((SCI2S1 & 0x20) == 0x20 )
DATA[Offset++] = SCI2D;
if(Offset&=0x02)
dummy = (unsigned int)(DATA[1])&&8;
dummy += DATA[0];
if(dummy&=0x1000)
Offset = 0;
*///====================================================//SCI1通过485发送一个字节程序//====================================================void TERMIO_PutChar(unsigned char ch) {E_NET_TE;//禁止串口接收数据允许发送数据
while (!(SCI1S1 & 0x80));
/* wait for output buffer empty */
while(!SCI1S1_TDRE);//SCI发送器未空则等待
__RESET_WATCHDOG();
E_NET_RE;//禁止串口发送数据允许接收数据
}//====================================================//SCI1通过485发送多个字节程序//====================================================void Transmitnet (unsigned char *p,unsigned char num){
unsigned char k=0;
E_NET_TE;//禁止串口接收数据允许发送数据
while(k != num)
while (!(SCI1S1 & 0x80));
SCI1D = (*p++);
while (!SCI1S1_TC);
__RESET_WATCHDOG();
while(!SCI1S1_TDRE);//SCI发送器未空则等待E_NET_RE;//禁止串口发送数据允许接收数据 }
//#include &MC68HC908GP32.h& /* include peripheral declarations */#include &MC9S08AW32.h& /* include peripheral declarations */#include &cnxdef.h&#include &cnxcest.h&#include &cnxsci.h&/*======设备信息存储区==================================================*说明:调光板在接收到Cresnet上的主控设备信息查询命令后*
要将下面的数据送出。*----------------------------------------------------------------------文本信息表示:Smartisys-IPXB-12 v3.00*//* unsigned char MachInf[28]={
//设备信息数据0x02,0x1A,0x05,0x00,0x00,0x53,0x6D,0x61,0x72,0x74,//Smart0x69,0x73,0x79,0x73,0x2D,0x49,0x50,0x58,0x42,0x2D,0x31,0x32,0x20,0x76,0x33,0x2E,0x30,0x30}; */ unsigned char Ack[2]={ //应答数据0x02,0x00};void ActionAn(void)//dimming{
chdata = ((unsigned int)CresRec5&&8) + ((unsigned int)SCIRecBuf);
__RESET_WATCHDOG();
dmxpwm1(); //产生PWM
Cresnet协议应答子程序
*======================================================================*说明:在此子程序中将执行响应查询、处理和发送数据的操作。*----------------------------------------------------------------------*/void CresAswSub(void){E_NET_TE;//禁止串口接收数据允许发送数据
if (AnotFlag_InqExi) //发送设备信息
for(i=0;i&4;i++)
TERMIO_PutChar(MachInf[i]) ;
AnotFlag_InqExi = 0;//发送完毕则清除系统查询命令存在标志
else //系统查询命令不存在则发送应答数据
Transmitnet(Ack,2);//串口发送0200
while(!SCI1S1_TDRE);//SCI发送器未空则等待E_NET_RE;//禁止串口发送数据允许接收数据
__RESET_WATCHDOG();}/*
执行Cresnet协议子程序
**======================================================================*说明:在此子程序中将依根据Cresnet协议的不同数据,分别执行*
开启应答、关闭应答、忽略数据、响应查询和返回数据等不同的操作。*
接收进的数据有两种格式:38400-Space-8-1和38400-Mark-8-1,*
发送出的数据只有一种格式:38400-Mark-8-1。*----------------------------------------------------------------------*/void CresAgrSub(void){PTADD = 0x03;
PTAD = 0x00;//485使能RE引脚 if(SCI1S1_RDRF)//接收到数据
PTGD_PTGD0
//清除接收器满的标志SCRF
SCIRecBuf = SCI1D;//取数据
__RESET_WATCHDOG();
if (!SCI1C3_R8)//接收位8为0
if (SCIRecBuf)//判断数据是否为$00
AnotFlag_AnsPer = 0;//不等于$00,禁止Cres协议查询应答
else//等于$00,转复位变量
FlagCell_CRExi1 = 0;
FlagCell_CRExi2 = 0;
FlagCell_CRExi3 = 0;
FlagCell_CRExi4 = 0;
FlagCell_CRExi5 = 0;
FlagCell_CRExi6 = 0;
AnotFlag_AnsPer = 1;//允许Cres协议查询应答
//清除Cres协议记录的第123456字节存在的标志
AnotFlag_TempAns=1;//ANET连通标志
else //接收位8为1
if (AnotFlag_AnsPer)//应答允许则判断记录的第1字节是否存在
AnotFlag_TempAns=0;//检测不到00时,关ANET连通标志
if (!FlagCell_CRExi1)//第1字节不存在则写入第1字节缓存
CresRec1 = SCIRecB
FlagCell_CRExi1 = 1;//给出记录的第1字节存在的标志
else//第1字节存在则判断记录的第2字节是否存在
if (!FlagCell_CRExi2)
if (SCIRecBuf)
CresRec2 = SCIRecB//不等于$00则写入第2字节缓存,
//此字节中的数据为此项记录的尚未接收到的字节数
FlagCell_CRExi2 = 1;//给出记录的第2字节存在的标志
else//00准备应答
{//判断第1字节是否在ID号取值范围内
if (CresRec1 == ID)//相等进行应答处理
CresAswSub();
//FlagCell = 0;//清除Cres协议记录的第1字节存在的标志
FlagCell_CRExi1 = 0;
CresRec2--;//一项记录数据尚未接收的字节数减1
if (!FlagCell_CRExi3)
if (CresRec2)//取此项记录尚未接收的字节数
CresRec3 = SCIRecB//不等于$00则写入第3字节缓存,
FlagCell_CRExi3 = 1;//给出记录的第3字节存在的标志
//清除Cres协议记录的第12字节存在的标志
FlagCell_CRExi1 = 0;
FlagCell_CRExi2 = 0;
if (!FlagCell_CRExi4)
if (CresRec2)//取此项记录尚未接收的字节数
CresRec4 = SCIRecB
FlagCell_CRExi4 = 1;
else//为0则判断此四字节是否为系统查询命令
{//或者是改ID号
if ((CresRec1==0xff) && (CresRec3==0x03)&&(SCIRecBuf == 0x01))
AnotFlag_InqExi = 1;//系统查询命令存在的标志
FlagCell_CRExi1 = 0;
FlagCell_CRExi2 = 0;
FlagCell_CRExi3 = 0;
//清除Cres协议记录的第123字节存在的标志
if (!FlagCell_CRExi5)
if (CresRec2)//判断记录的第2字节当前值
CresRec5 = SCIRecB
FlagCell_CRExi5 = 1;
FlagCell_CRExi1 =0;
FlagCell_CRExi2 =0;
FlagCell_CRExi3 =0;
FlagCell_CRExi4 =0;
if (!FlagCell_CRExi6)
if (CresRec2)
FlagCell_CRExi6 = 1;
if ((CresRec1==ID) && (CresRec3==0x1)) //是调光控制命令则调用调光子程序处理
ActionAn();
FlagCell_CRExi1 = 0;
FlagCell_CRExi2 = 0;
FlagCell_CRExi3 = 0;
FlagCell_CRExi4 = 0;
FlagCell_CRExi5 = 0;
FlagCell_CRExi6 = 0;
//FlagCell = 0;
if (!CresRec2)
//FlagCell = 0;
FlagCell_CRExi1 = 0;
FlagCell_CRExi2 = 0;
FlagCell_CRExi3 = 0;
FlagCell_CRExi4 = 0;
FlagCell_CRExi5 = 0;
FlagCell_CRExi6 = 0;
}//第3字节存在
}//第2字节存在
}//第1字节存在
}//应答不允许
}//接收位8为1
PTGD_PTGD0 = 1;
}//接收不到数据
__RESET_WATCHDOG();}
登录百度帐号推荐应用

我要回帖

更多关于 电池给单片机供电 的文章

 

随机推荐