找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3754|回复: 4
打印 上一主题 下一主题
收起左侧

STC15F104W编码器两路可调PWM输出源程序

  [复制链接]
跳转到指定楼层
楼主
ID:486426 发表于 2020-9-8 07:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//没有用IAPIDLE功能,有没有高手指点一下利弊
#include <STC15F104E_PLUS.h>
#include <intrins.h>
typedef unsigned char BYTE;
typedef unsigned int WORD;
//#define uint unsigned int
//#define MAIN_Fosc                22118400L        //定义主时钟
//#define MAIN_Fosc                12000000L        //定义主时钟
#define MAIN_Fosc                11059200L        //定义主时钟
//#define MAIN_Fosc                 5529600L        //定义主时钟
//#define MAIN_Fosc                24000000L        //定义主时钟
//#define MAIN_Fosc                40000000L        //定义主时钟
//#define ENABLE_IAP 0x80           //if SYSCLK<30MHz
//#define ENABLE_IAP 0x81           //if SYSCLK<24MHz
//#define ENABLE_IAP  0x82          //if SYSCLK<20MHz
#define ENABLE_IAP 0x83           //if SYSCLK<12MHz
//#define ENABLE_IAP 0x84           //if SYSCLK<6MHz
//#define ENABLE_IAP 0x85           //if SYSCLK<3MHz
//#define ENABLE_IAP 0x86           //if SYSCLK<2MHz
//#define ENABLE_IAP 0x87           //if SYSCLK<1MHz
#define CMD_IDLE    0               //空闲模式
#define CMD_READ    1               //IAP字节读命令
#define CMD_PROGRAM 2               //IAP字节编程命令
#define CMD_ERASE   3               //IAP扇区擦除命令
//测试地址
#define IAP_ADDRESS1 0X0000         //内部EEPROM地址
#define IAP_ADDRESS2 0X0200
/*初始定义*/
bit  write = 0;
sbit VD=P3^3;  //红色LED 0.50v=10v ;1.00=27v ;3.85=73v;
sbit CD=P3^4;  //绿色LED
sbit ZS=P3^5;  //指示LED转换  0 - 红色LED调整;1 - 绿色LED调整
sbit BA=P3^0;  //编码器的a脚接P3.0
sbit BB=P3^1;  //编码器的b脚接P3.1
sbit QH=P3^2;  //编码器的按键接P3.2 电压调整或电流调整299=5.00V
BYTE v_temp,c_temp,XZ = 0,flag,a0,b0,c0;//  128 109  48 29  //48=0.96V;29=0.58V;
void InitTimer0() interrupt 1  // 0.5毫秒@11.0592MHz  频率 1000HZ
{
    IE2 = 0x00;    //关闭定时器2中断
    AUXR = 0XE4;   //关闭定时器2计数
    TL0 = 0xCD;    //设置定时初值 0.5毫秒@11.0592MHz
    TH0 = 0xD4;    //设置定时初值 0.5毫秒@11.0592MHz
    VD = 1;
    CD = 1;
    flag = 1;
    AUXR = 0xF4;   //开启定时器2计数
    IE2 = 0x04;    //开启定时器2中断允许
}

void InitTimer2() interrupt 12    //2微秒@11.0592MHz 控制灯亮时间
{
    flag++;
    T2L = 0xD4;    //设置定时初值 2微秒@11.0592MHz
    T2H = 0xFF;    //设置定时初值 2微秒@11.0592MHz
    if(v_temp == flag) VD=0;
    if(c_temp == flag) CD=0;
}

/*//关闭IAP
void IapIdle()
{
    IAP_CONTR = 0;                  //关闭IAP功能
    IAP_CMD = 0;                    //清除命令寄存器
    IAP_TRIG = 0;                   //清除触发寄存器
    IAP_ADDRH = 0x80;               //将地址设置到非IAP区域
    IAP_ADDRL = 0;
}
*/
//从ISP/IAP/EEPROM区域读取一字节
BYTE IapReadByte(WORD addr)
{
    BYTE dat;                       //数据缓冲区
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_READ;             //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
    //IapIdle();                    //关闭IAP功能
    return dat;                     //返回

}

//写一字节数据到ISP/IAP/EEPROM区域
void IapProgramByte(WORD addr, BYTE dat)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_PROGRAM;          //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_DATA = dat;                 //写ISP/IAP/EEPROM数据
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    //IapIdle();

}

//扇区擦除
void IapEraseSector(WORD addr)
{
    IAP_CONTR = ENABLE_IAP;         //使能IAP
    IAP_CMD = CMD_ERASE;            //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    //IapIdle();

}


/*void Timer0Init(void)                //100微秒@24.000MHz  10KHZPWM
{
        AUXR |= 0x80;        //定时器时钟1T模式
        TMOD &= 0xF0;   //设置定时器模式
        TL0 = 0xA0;                //设置定时初值--100微秒@24.000MHz
        TH0 = 0xF6;                //设置定时初值--100微秒@24.000MHz
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
}

void Timer2Init(void)//0.4微秒@24.000MHz
{
        AUXR |= 0x04;  //定时器时钟1T模式
        T2L = 0xF6;           //设置定时初值--0.4微秒@24.000MHz
        T2H = 0xFF;           //设置定时初值--0.4微秒@24.000MHz
        AUXR |= 0x10;  //定时器2开始计时
}
*/
void bianmaqi(void)//捕捉EC11按下和旋转信息
{
  unsigned char a, b, c;
  a = BA; b = BB; c = QH;
   if (a != a0)     // BA changed
  {
        a0 = a;
    if (b != b0)    // BB changed
     {
      b0 = b;write = 1;
        if ((a == b) && (XZ == 0) && (v_temp < 153)) {v_temp++;}//225 153
    if ((a == b) && (XZ == 1) && (c_temp < 73)) {c_temp++;}//208 65
    if ((a != b) && (XZ == 0) && (v_temp > 23)) {v_temp--;}//85 23   
        if ((a != b) && (XZ == 1) && (c_temp > 5)) {c_temp--;}//29 5
     }
    }
  if (!c && c0)
        {
        if (XZ == 0 )
      {
        XZ = 1;
        ZS = 1;
        }
    else if(XZ == 1)//切换
      {
            XZ = 0;
        ZS = 0;
       }
    }
    c0 = c;
}
void init()
{
    AUXR = 0XE4;   //设置定时器0和2为1T模式
    TMOD = 0x00;
    TL0 = 0xCD;    //设置定时初值 0.5毫秒@11.0592MHz 0xA0;--100微秒@24.000MHz
    TH0 = 0xD4;    //设置定时初值 0.5毫秒@11.0592MHz 0xFF;--0.4微秒@24.000MHz
    T2L = 0xD4;    //设置定时初值 2微秒@11.0592MHz 0xF6;--0.4微秒@24.000MHz
    T2H = 0xFF;    //设置定时初值 2微秒@11.0592MHz 0xFF;--0.4微秒@24.000MHz
    EA = 1;
    ET0 = 1;
    TR0 = 1;       //定时器0开始计时
    P3M1 &= 0xF7;
    P3M0 |= 0x08;  //P3.3(推挽)
    P3M1 &= 0xEF;
    P3M0 |= 0x10;  //P3.4(推挽)
    P3M1 &= 0xDF;
    P3M0 |= 0x20;  //P3.5(推挽)
    VD = 0;
    CD = 0;
    ZS = 0;        // 0 - 电压调整状态;1 - 电流调整状态
    a0 = BA;
    b0 = BB;
    c0 = QH;
          v_temp = IapReadByte(1);
        if (v_temp == 0 ){v_temp = 65;}     //128        65
        if (v_temp > 153){v_temp = 65;}     //245  128   
        c_temp = IapReadByte(10);
    if (c_temp == 0 ){c_temp = 29;}     //109           
    if (c_temp > 29 ){c_temp = 29;}     //208  109  

}
void main()
{
init();
while(1)
   {
   bianmaqi();
   if (write == 1) {
          write = 0;TR0 = 0;
      IapEraseSector(IAP_ADDRESS1);//擦除扇区
      if (XZ == 0 )  {
      IapProgramByte(1,v_temp);   //写入数据
                   }
        else  if (XZ == 1 )  {
      IapProgramByte(10,c_temp);  //写入数据
                   }
   }
   _nop_();
   TR0 = 1;
   }
}

STC15F104W编码器两路可调PWM输出.rar

29.74 KB, 下载次数: 114, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:245466 发表于 2020-12-8 21:33 | 只看该作者
这个太好了,正好做参考!
回复

使用道具 举报

板凳
ID:230374 发表于 2021-3-29 10:43 | 只看该作者
很好的,学习备用,谢谢
回复

使用道具 举报

地板
ID:796531 发表于 2021-4-5 14:58 | 只看该作者
学习,正在学习PWM,谢谢
回复

使用道具 举报

5#
ID:693367 发表于 2021-5-17 08:16 来自手机 | 只看该作者
哪位大佬帮我写一个stc15F104w单片机爆闪灯,p3.2和p3.3接爆闪灯,每个灯闪3次循环爆闪用按键可以调节爆闪频率
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表