caniggia的笔记 https://bbs.21ic.com/?520249 [收藏] [复制] [RSS] 用笔和镜头记录生活,这里我用的是键盘!

日志

自己写的STC12C4052AD部分底层C语言库

已有 1251 次阅读2010-5-21 08:43 |个人分类:MCU / IC 应用|系统分类:单片机| STC12C4052AD, STC12C2052AD

/*自己编写的STC12C4052AD底层库文件,已上机调试过,希望能给初次用这块单片机的人一些帮助,希望大家支持,谢谢*/


/************************************************************************/
/* Name: STC12C4052AD_LIB.C                                             */
/* Language: C51单片机编程语言                                          */
/* Platform:                                                            */
/* Author:  FRANK FONG  , huananfang@hotmail.com                                 */
/* Date: 2010-05-21,上海;                                              */
/* Version:                                   */
/* Deion: AD ; PWM ; EEPROM                                       */
/************************************************************************/



#include <STC12C2052AD.H>
#include <string.h>
#include <intrins.h>
#define ENABLE_ISP 0x8A    //10001010,打开ISP功能,设置Flash时间



typedef unsigned char  INT8U;
typedef unsigned int   INT16U;



//关闭ISP 功能, 清相关的特殊功能寄存器
void ISP_Disable()
{
    ISP_CONTR = 0;      //关闭ISP 功能
    ISP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
    ISP_TRIG  = 0;      //清命令触发寄存器,使命令触发寄存器无触发
    ISP_ADDRH = 0;
    ISP_ADDRL = 0;
}


//eeprom  寻址共用体
union union_temp16
{
    INT16U un_temp16;
    INT8U  un_temp8[2];
}my_unTemp16;


//延时函数
void delay(INT8U delay_time)  
{
    INT16U n;
    while(delay_time--)
    {
        n = 6000;
        while(--n);
    }
}


//adc初始化 ( 已放在AD转换 里面)
//void adc_power_on()    
//{
// ADC_CONTR = 0xC0;   //11000000,开AD电源,SPEED 420时钟周期转换一次,缺省选通道P1.0
// delay(1);     //开A/D转换电源后要加延时
//}


//adc_power_off
//void adc_power_off()    
//{
// ADC_CONTR &= 0x7F;         
// delay(1);
//}


//AD转换
INT8U adc_result (INT8U channel)     

 
 
 INT8U DATA_adccontr = 0xC0;
 channel &= 0x07;                  //0000,0111 清0高5位
 DATA_adccontr = 0xC0 + channel;   //选AD通道,0-p10,1-p11,2-p12,3-p13,4-p14
 ADC_CONTR = DATA_adccontr;    //开AD电源,SPEED 420时钟周期转换一次
 
 delay(1);        //开A/D转换电源后要加延时


 DATA_adccontr=DATA_adccontr&0xef;  //与11101111对adc_flag清0
 ADC_CONTR=DATA_adccontr;
 DATA_adccontr=DATA_adccontr|0x08;  //或1000 对ADC_START置位,开始ADC
 ADC_CONTR=DATA_adccontr;
 delay(1);        //延时


 while (1)                         //等待A/D转换结束
    {
        if (ADC_CONTR & 0x10)         //0001,0000 测试A/D转换结束否
        {
   break;
  }
    }
    ADC_CONTR &= 0xE7;                //与1110,0111 清 ADC_FLAG 位, 关闭A/D转换


 return ADC_DATA;      //返回 A/D 8 位转换结果
}


//读一字节,调用前需打开ISP功能
INT8U Byte_Read(INT16U add)
{
 ea=0;
 ISP_DATA = 0x00;
 ISP_CONTR = ENABLE_ISP;  //10001010,打开ISP功能,设置Flash时间
 ISP_CMD = 0x01;             //IAP/ISP/EEPROM 字节读命令
 my_unTemp16.un_temp16 = add;
    ISP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
    ISP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址
 
 ISP_TRIG = 0x46;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    ISP_TRIG = 0xB9;   //送完A5h 后,ISP/IAP 命令立即被触发起动
  _nop_();
 ISP_Disable();
 return (ISP_DATA);
}


//写字节编程,调用前需打开ISP 功能
void Byte_Program (INT16U add, INT8U ch )
{
    ISP_CONTR = ENABLE_ISP;         //打开 ISP 功能
    ISP_CMD = 0x02;                 //IAP/ISP/EEPROM 字节编程命令


    my_unTemp16.un_temp16 = add;
    ISP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
    ISP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址


    ISP_DATA = ch;          //要编程的数据先送进ISP_DATA 寄存器


    ISP_TRIG = 0x46;     //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    ISP_TRIG = 0xB9;     //送完A5h 后,ISP/IAP 命令立即被触发起动
    _nop_();


    ISP_Disable();    //关闭ISP 功能                  
}


//擦除扇区
void Sector_Erase(INT16U add)
{
    ISP_CONTR = ENABLE_ISP;         //打开ISP 功能
    ISP_CMD = 0x03;                 //IAP/ISP/EEPROM 扇区擦除命令


    my_unTemp16.un_temp16 = add;
    ISP_ADDRH = my_unTemp16.un_temp8[0];    //设置目标单元地址的高8 位地址
    ISP_ADDRL = my_unTemp16.un_temp8[1];    //设置目标单元地址的低8 位地址



    ISP_TRIG = 0x46;   //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此
    ISP_TRIG = 0xB9;   //送完A5h 后,ISP/IAP 命令立即被触发起动
    _nop_();


    ISP_Disable();  //关闭IAP 功能
}



//pwm初始化 ,p3.7 输出PWM
void pca_init()
{
   CMOD=0x82;            //10000010内部时钟Fosc/2
    CCON=0x00;    //pca  flag  clear ,pca is stop
    CL=0x00;
    CCAPM0=0x42;   //01000010 ,set pwm mode,使能 CEX0 脚作脉宽调节PWM输出
    PCA_PWM0=0x00;       // (EPCnH)在pwm模式下,与CCAPnH组成9位数
                      // (EPCnL)在pwm模式下,与CCAPnL组成9位数,构成捕获寄存器
    tr1=1;        //开定时1     
    ea=1;     //开中断
    CR=1;     //启动PWM
}


 // p3.7 /CEX0输出 PWM
void pwm_run(INT8U pulse_with)
{
 //CCAP0L=pulse_with;
   pca_init();
    CCAP0H=pulse_with;
}


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)