51单片机制作舵机的程序单片机解密
- 单片机解密/******************************************/
- //
- // 主频12MHz !!!!
- //
- /******************************************/
- #include <reg51.h>
- #include <intrins.h>
- // 定义常用数据类型别名
- #define uchar unsigned char
- #define uint unsigned int
- #define u8 unsigned char
- #define u16 unsigned int
- #define int16 int
- // 定义PID参数
- #define KP 50 // 比例系数,可调整
- #define KI 10 // 积分系数,可调整
- #define KD 5 // 微分系数,可调整
- // 积分限幅
- #define INTEGRAL_LIMIT 1000
- //* STC15W408AS寄存器补充
- sfr AUXR1 = 0XA2;
- sfr AUXR = 0X8E;
- sfr TH2 = 0XD6;
- sfr TL2 = 0XD7;
- sfr P4 = 0xC0;
- sfr P5 = 0xC8;
- sfr SPSTAT = 0xCD;
- sfr SPCTL = 0xCE;
- sfr SPDAT = 0xCF;
- sfr P1M1 = 0x91;
- sfr P1M0 = 0x92;
- sfr P2M1 = 0x95;
- sfr P2M0 = 0x96;
- sfr P3M1 = 0xB1;
- sfr P3M0 = 0xB2;
- sfr P5M1 = 0xC9;
- sfr P5M0 = 0xCA;
- // 定时器2
- sfr T2H = 0xD6;
- sfr T2L = 0xD7;
- sfr IE2 = 0xAF;
- // ADC
- sfr ADC_CONTR = 0xBC; // 带AD系列
- sfr ADC_RES = 0xBD; // 带AD系列
- sfr ADC_RESL = 0xBE; // 带AD系列
- sfr P1ASF = 0x9D;
- sfr PCON2 = 0x97;
- // ADC控制位定义
- #define ADC_POWER 0x80// ADC电源控制位
- #define ADC_FLAG 0x10// ADC完成标志
- #define ADC_START 0x08// ADC起始控制位
- #define ADC_SPEEDLL 0x00// 540个时钟转换一次
- #define ADC_SPEEDL 0x20// 360时钟
- #define ADC_SPEEDH 0x40// 180时钟
- #define ADC_SPEEDHH 0x60// 90时钟
- // 电机控制引脚
- sbit IA = P3^7;
- sbit IB = P3^6;
- // PPM信号相关变量
- u8 PPMCnt = 0; // 收到PPM脉冲的次数
- bit PPMOK = 0; // 是否收到一个PPM脉冲
- u16 time; // PPM的高电平计数
- // ADC采样相关变量
- u16 ad[10]; // 存放10个ad数值的数组
- u16 ad1 = 0; // 舵机的电位器的ad值
- u16 ad0 = 0; // 舵机的电位器应该达到的AD值
- // 电机运行时间
- u8 t1; // 电机运行持续毫秒数
- // PID相关变量
- int16 integral = 0; // 积分项
- int16 lastError = 0; // 上一次的误差
- int16 error;
- int16 derivative;
- /***************/
- /* 延时函数 */
- /***************/
- // 1ms延时函数
- void Delay1ms() //@12.000MHz
- {
- unsigned char i, j;
- i = 12;
- j = 169;
- do
- {
- while (--j);
- } while (--i);
- }
- // 毫秒级延时函数
- void delay_ms(unsigned char i)
- {
- while (i--)
- {
- Delay1ms();
- }
- }
- // 获取10位精度的ADC值
- u16 Get_ADC10bitResult(u8 channel)
- {
- u16 adc;
- if (channel > 7) return 1024; // 错误,返回1024, ADC通道号0~7,不能超过7
- ADC_RES = 0; // 高位ADC清零
- ADC_RESL = 0; // 低位ADC清零
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | channel; // 打开指定通道的ADC转换
- _nop_();
- _nop_();
- _nop_();
- _nop_(); // 对ADC_CONTR操作后要4T之后才能访问
- while (!(ADC_CONTR & ADC_FLAG)); // 等待ADC转换完成
- ADC_CONTR &= ~ADC_FLAG; // ADC_FLAG手工清0,关闭 ADC
- adc = ADC_RES; // 得到高8位
- adc <<= 2;
- adc += ADC_RESL; // 得到低2位
- return adc;
- }
- // 定时器0初始化函数 当INT0也就是P3.2脚为高,定时器0才开始运行
- void Timer0Init(void) //12.000MHz
- {
- AUXR &= 0x7F; // 定时器时钟12T模式
- TMOD = 0x09; // 16位不可重装模式 当INT0=1和TR0=1时,定时器0才能运行
- TL0 = 0x00; // 设置定时初值
- TH0 = 0x00; // 设置定时初值
- TF0 = 0; // 清除TF0标志
- TR0 = 1; // 定时器0开始计时
- ET0 = 1; // 允许ET0中断
- EA = 1; // 允许全部中断
- }

芯片解密