论坛风格切换切换到宽版
  • 3476阅读
  • 3回复

MC145158的例程(C语言,所有程序未经验证!求电路图) [复制链接]

上一主题 下一主题
离线wb4916
 
发帖
213
只看楼主 倒序阅读 0楼 发表于: 2009-12-03
看代码是asm版本的,大家/自己理解起来诸多不便,于是转换成c语言版本之后再理解了,利己达人!
注意:为了便于大家查看。所有的空格就转给不可见字符了。20 20 20 20 转 a1 a1 a1 a1
请大家下载附件中的代码编译,请勿直接复制!




// http://www.eetop.cn/bbs/thread-11161-1-1.html
//
// 各位 老师请帮忙看一下程序 偶看的不是很懂
// 这是一个关于mc145158的编成 其中是用的51芯片组


#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char  // one byte
#define uint unsigned int       //two bytes


uint rcount = 256;
uint ncount = 724;
uint acount = 0;

uint dptr = 0;

sbit clock = p1^0;
sbit data1 = p1^1;
sbit lock = p1^2;

uchar i = 0;
uchar j = 0;
uchar temp = 0;
uchar tempr1 = 0;

uchar dph2 = 0;
uchar tempr0 = 0;

uchar temp20 = 0;
uchar temp21 = 0;
uchar temp22 = 0;
uchar temp23 = 0;
uchar temp24 = 0;

uchar temp40 = 0;
uchar temp41 = 0;


// 2009-12-3 10:20 函数声明
void rsout1(void);
void nasout1(void);
void deltime1(void);


void main(void)
{
  while(1)
  {
    // org0000h:
    rcount = 256;
    ncount = 724;
    acount = 0;
    
    
    temp24 = (rcount&0xff00)>>8;
    temp23 = rcount&0x00ff;
    // rsout1(rcount);
    rsout1();

    
    // naccess:
    do
    {
      dptr = ncount;
      temp22 = (ncount&0xff00)>>8;
      temp21 = ncount&0x00ff;
      
      temp20 = acount;
      
      // tempr0 = temp20;
      tempr0 = 0x20;
      
      lock = 0;
      
      
      // natatout
      do
      {
        nasout1();
        deltime1();
        temp20++;
      }while(127!=temp20);
      
      deltime1();
      
      tempr1 = 1;
      // nincreas
      do
      {
        // 2009-12-3 11:01
        dptr++;
        tempr1--;
      }while(tempr1);
      
      deltime1();
      
      // if(dph2&0x01)
      // {
      //   goto naccess;
      // }
      
      dph2 = (dptr&0x80)>>8;
    }while(!(dph2&0x01));
    
    
    _nop_();
    
    // goto org0000h;
  }
}


void rsout1(void)
{
  temp = temp24;
  for(i=0;i<8;i++)
  {
    if(temp&0x80)
    {
      data1 = 1;
    }
    else
    {
      data1 = 0;
    }
    
    _nop_();
    
    clock = 1;
    _nop_();_nop_();
    
    clock = 0;
    _nop_();
    
    temp <<= 1;    
  }
  
  // rsout2
  temp = temp23;
  for(i=0;i<8;i++)
  {
    if(temp&0x80)
    {
      data1 = 1;
    }
    else
    {
      data1 = 0;
    }
    
    _nop_();
    
    clock = 1;
    _nop_();_nop_();
    
    clock = 0;
    _nop_();
    
    temp <<= 1;    
  }
  
    data1 = 1;
    _nop_();
    
    clock = 1;
    _nop_();_nop_();
    
    clock = 0;
    _nop_();
    
    clock = 1;
    _nop_();_nop_();_nop_();_nop_();
    
    lock = 0;
}


void nasout1(void)
{
  temp = temp22;  
  for(i=0;i<8;i++)
  {
    if(temp&0x80)
    {
      data1 = 1;
    }
    else
    {
      data1 = 0;
    }
    
    _nop_();
    
    clock = 1;
    _nop_();_nop_();
    
    clock = 0;
    _nop_();
    
    temp <<= 1;
  }
  
  // nasout2
  temp = temp21;
  for(i=0;i<8;i++)
  {
    if(temp&0x80)
    {
      data1 = 1;
    }
    else
    {
      data1 = 0;
    }
    
    _nop_();
    
    clock = 1;
    _nop_();_nop_();
    
    clock = 0;
    _nop_();
    
    temp <<= 1;
  }
  
  // nasout3
  temp = temp20;
  temp <<= 1;
  for(i=0;i<7;i++)
  {
    if(temp&0x80)
    {
      data1 = 1;
    }
    else
    {
      data1 = 0;
    }
    
    _nop_();
    
    clock = 1;
    _nop_();_nop_();
    
    clock = 0;
    _nop_();
    
    temp <<= 1;
  }
  
  // return
  data1 = 0;
  _nop_();
  
    clock = 1;
    _nop_();_nop_();
    
    clock = 0;
    _nop_();
  
  clock = 1;
  _nop_();_nop_();_nop_();_nop_();
  
  lock = 0;
}


void deltime1(void)
{
  temp40 = 15;
  temp41 = 25;
  
  for(i=0;i<15;i++)
  {
      lock = 0;
      _nop_();
      
    for(j=0;i<25;j++)
    {

      
      lock = 0;
      _nop_();_nop_();
    }
  }
  
  _nop_();
}
本主题包含附件,请 登录 后查看, 或者 注册 成为会员
离线wb4916
发帖
213
只看该作者 1楼 发表于: 2009-12-03
代码是asm版本的,大家/自己理解起来诸多不便,于是转换成c语言版本之后再理解了,利己达人!
注意:为了便于大家查看。所有的空格就转给不可见字符了。20 20 20 20 转 a1 a1 a1 a1
请大家下载附件中的代码编译,请勿直接复制!




#include <regx51.h>
#define uchar unsigned char  // one byte
#define uint unsigned int       //two bytes


#define reference_frequency 2000//参考频率1khz

#define      a_start_counter      0
#define      n_start_counter      950

#define max_a_counter      19            //max_a_counter=p-1
#define min_a_counter      0

#define max_n_counter      16383
#define min_n_counter      19


// 2009-12-3 11:33 函数声明
void mc145158_wirte_reference_counter_latch(uint reference_counter);      
void mc145158_wirte_a_n_counter_latch(uchar a_counter,uint n_counter);
uchar getkey(void);
void time_delay(uint time_delay);

void main(void)
{
  
  uchar a_counter;
  uint n_counter;
  
  /*初始化p1*/
  p1=0;      
  /*调用分频比函数,向reference_counter_latch写分频比,设置参考频率*/
  mc145158_wirte_reference_counter_latch(reference_frequency);
  
  mc145158_wirte_a_n_counter_latch(a_start_counter,n_start_counter);
  
  a_counter=a_start_counter;
  n_counter=n_start_counter;
  
  while (1)
  {
    
    switch (getkey())
    
    {
      case 0:
        {
          p1_2=!p1_2;
          a_counter++;
          
          if (a_counter>max_a_counter)
          {
            a_counter=min_a_counter;
            n_counter++;      //bug
          }
          
          mc145158_wirte_a_n_counter_latch(a_counter,n_counter);
          
          break;
        }
        
      case 1:
        {
          p1_2=!p1_2;
          
          if (a_counter==min_a_counter)
          {
            n_counter--;            //bug
            a_counter=max_a_counter;
          }
          else
          {
            a_counter--;
          }
          
          mc145158_wirte_a_n_counter_latch(a_counter,n_counter);
          
          break;
        }
        
      case 3:
        {
          ;
        }
        
    }
  }
  
}


/*p1_0和p1_1作为增减频率的输入键,p1_2作为键盘输入的指示灯*/
uchar getkey(void)
{
  if (p1_0==1) /*检查p1_0是否按下,如果未按下检查p1_1*/  
  {
      if (p1_1==1)
    return 3;/*检查p1_0是否按下,如果未按下返回数值3*/    
    else
    {
      time_delay(5000);/*延时再检查,如果仍为低电平则按键有效*/
      
      if (p1_1==0)
        return 1;
      else
        return 3;
    }
  }
  else /*p1_0按下*/
  {
    time_delay(5000);/*延时再检查,如果仍为低电平则按键有效*/
    
    if (p1_0==0)
      return 0;
    else
      return 3;
  }
}


/*本函数作为不精确的延时使用*/
void time_delay(uint time_delay)      //time_delay定义为时延长短
{
  uint time_delay_counter;            //延时设计中,作为循环时计数器
  
  for (time_delay_counter=0; time_delay_counter<time_delay; time_delay_counter++)
  {
    ;
  }
}


void mc145158_wirte_reference_counter_latch(uint reference_counter)
{
  uchar reference_counter_l;      //reference_counter低位
  uchar reference_counter_h;      //reference_counter高位
  uchar bit_shift;            //存放reference_counter移位、位运算后的中间结果,
  
  uchar bit_shift_counter;      //移位计数器
  
  /*将reference_counter整形,加入控制位*/
  reference_counter=      reference_counter<<2 | 0x0002;            
  
  
  /*将reference_counter高低字节分两次写入。      先写入高字节(其最高位有意义),后写入低字节
  (其倒数第二位为控制位,最低位无意义).通过位运算实现串行写入:reference_counter_l(or_h)
  每左移1位,然后0x01111111进行一次或运算,如果p1_7==1,或运算的结果与p1进行一次与运算,否则令p1_7==1再进行与运算
  reference_counter_l(or_h)中各位就可逐位输出到p1_7=data.      */
  
  reference_counter_l=reference_counter;      //发生数据类型转换,char类型得到int的低字节                  
  reference_counter_h=reference_counter >>8;      //右移位,得到int的高字节
  
  
  /*取p1口的7、6、5pin分别对应data、clk和enb:      p1_7=data      p1_6=clk      p1_5=enb      */
  
  p1_5=0;            //先将enb置0,(置0时,锁存器内容不随移位寄存器改变而改变),准备从p1_7=data写入数据
  p1_6=0;            //p1_6初始化
  
  
  /*以下程序写入高字节*/
  bit_shift_counter=0;            //移位计数器初始化
  while (bit_shift_counter<8)      //写入高字节的8位数据,全部有效
  {
    
    bit_shift=(reference_counter_h | 0x7f);      //reference_counter_h与0x01111111进行一次或运算,中间结果存入bit_shift
    p1_7=1;                              //保证与运算前,p1_7置1
    p1=bit_shift & p1;                  //bit_shift与p1进行一次与运算,使p1口的其他引脚状态不变,而p1_7发生变化
    p1_6=1;                              //p1_6=clk产生一个上升沿,使p1_7数据进入mc145158的控制寄存器
    
    p1_6=0;                              //p1_6置位
    reference_counter_h=reference_counter_h<<1;      //reference_counter_h左移1位
    bit_shift_counter ++;
  }
  
  
  /*一下写入低字节*/
  bit_shift_counter=0;            //移位计数器初始化
  while (bit_shift_counter<7)      //写入低字节的高7位数据,丢弃最地位
  {
    
    bit_shift=(reference_counter_l | 0x7f);      //reference_counter_l与0x01111111进行一次或运算,中间结果存入bit_shift
    p1_7=1;                                    //保证与运算前,p1_7置1
    p1=bit_shift & p1;                  //bit_shift与p1进行一次与运算,使p1口的其他引脚状态不变,而p1_7发生变化
    p1_6=1;                              //p1_6=clk产生一个上升沿,使p1_7数据进入mc145158的控制寄存器
    
    
    p1_6=0;                              //p1_6置位
    reference_counter_l=reference_counter_l<<1;      //reference_counter_l左移1位
    bit_shift_counter ++;
  }
  
  
  /*通过p1_5(enb)置位,将reference_counter中数据写入锁存器reference counter latch */
  p1_5=1;
  
  /*通过p1_5(enb)复位*/
  p1_5=0;
}


void mc145158_wirte_a_n_counter_latch(uchar a_counter,uint n_counter)
{
  uchar n_counter_l;      //n_counter低位
  uchar n_counter_h;      //n_counter高位
  uchar bit_shift;      //存放a_n_counter移位、位运算后的中间结果,
  
  uchar bit_shift_counter;      //移位计数器
  
  
  /*将n_counter高低字节分两次写入。      先写入高字节(其最高位有意义),后写入低字节
  (其倒数第二位为控制位,最低位无意义).通过位运算实现串行写入:n_counter_l(or_h)
  每左移1位,然后0x01111111进行一次或运算,如果p1_7==1,或运算的结果与p1进行一次与运算,否则令p1_7==1再进行与运算
  n_counter_l(or_h)中各位就可逐位输出到p1_7=data.      */
  
  n_counter_l=n_counter;      //发生数据类型转换,char类型得到int的低字节                  
  n_counter_h=n_counter >>8;      //右移位,得到int的高字节
  
  
  /*取p1口的7、6、5pin分别对应data、clk和enb:      p1_7=data      p1_6=clk      p1_5=enb      */
  
  p1_5=0;            //先将enb置0,(置0时,锁存器内容不随移位寄存器改变而改变),准备从p1_7=data写入数据
  p1_6=0;            //p1_6初始化
  
  
  /*以下程序写入高字节*/
  bit_shift_counter=0;            //移位计数器初始化
  while (bit_shift_counter<8)      //写入高字节的8位数据,后2位有效
  {
    
    bit_shift=(n_counter_h | 0x7f);      //n_counter_h与0x01111111进行一次或运算,中间结果存入bit_shift
    p1_7=1;                              //保证与运算前,p1_7置1
    p1=bit_shift & p1;                  //bit_shift与p1进行一次与运算,使p1口的其他引脚状态不变,而p1_7发生变化
    p1_6=1;                              //p1_6=clk产生一个上升沿,使p1_7数据进入mc145158的控制寄存器
    
    p1_6=0;                              //p1_6置位
    n_counter_h=n_counter_h<<1;      //n_counter_h左移1位
    bit_shift_counter ++;
  }
  
  
  /*一下写入低字节*/
  bit_shift_counter=0;            //移位计数器初始化
  while (bit_shift_counter<8)      //写入低字节的8位数据
  {
    
    bit_shift=(n_counter_l | 0x7f);      //n_counter_l与0x01111111进行一次或运算,中间结果存入bit_shift
    p1_7=1;                                    //保证与运算前,p1_7置1
    p1=bit_shift & p1;                  //bit_shift与p1进行一次与运算,使p1口的其他引脚状态不变,而p1_7发生变化
    p1_6=1;                              //p1_6=clk产生一个上升沿,使p1_7数据进入mc145158的控制寄存器
    
    
    p1_6=0;                              //p1_6置位
    n_counter_l=n_counter_l<<1;      //n_counter_l左移1位
    bit_shift_counter ++;
  }
  
  /*将a_counter整形,加入控制位*/
  a_counter=a_counter<<1;      
  
  /*写入a_counter*/
  bit_shift_counter=0;            //移位计数器初始化
  while (bit_shift_counter<8)      //写入低字节的高8位数据
  {
    
    bit_shift=(a_counter | 0x7f);      //n_counter_l与0x01111111进行一次或运算,中间结果存入bit_shift
    p1_7=1;                                    //保证与运算前,p1_7置1
    p1=bit_shift & p1;                  //bit_shift与p1进行一次与运算,使p1口的其他引脚状态不变,而p1_7发生变化
    p1_6=1;                              //p1_6=clk产生一个上升沿,使p1_7数据进入mc145158的控制寄存器
    
    
    p1_6=0;                              //p1_6置位
    a_counter=a_counter<<1;      //n_counter_l左移1位
    bit_shift_counter ++;
  }
  
  
  /*通过p1_5(enb)置位,将n_counter中数据写入锁存器reference counter latch */
  p1_5=1;
  
  /*通过p1_5(enb)复位*/
  p1_5=0;
}
离线wb4916
发帖
213
只看该作者 2楼 发表于: 2009-12-03
看代码是asm版本的,大家/自己理解起来诸多不便,于是转换成c语言版本之后再理解了,利己达人!
注意:为了便于大家查看。所有的空格就转给不可见字符了。20 20 20 20 转 a1 a1 a1 a1
请大家下载附件中的代码编译,请勿直接复制!




// http://hi.baidu.com/lhgbevin/blog/item/8e8371f04ab201c17831aa30.html
//
// [原创]锁相环频率合成mc145158-2写频程序+液晶显示(头文件)
// 2007-08-06 23:52

#include "at89x52.h"
#include "my_lcm.h"


sbit en=p1^0;
sbit cdata=p1^1;
sbit clk=p1^2;


#define ulong unsigned long


uint r_counter;  //14bit,3~16383
uchar a_counter; //7bit,0~127
uint n_counter;   //10bit,3~1023
uint nh;   //总分频数
uchar fr;


// 2009-12-2 15:07 函数声明
// delay_1sm(uint t);


// delay_1sm(uint t)
delay_1ms(uint t)
{
  uint i,j;
  
  for(i=0;i<t;i++)
    for(j=0;j<120;j++)
  ;
}


void mc145158(uint osc,uchar p,uint fout)
{
  r_counter=1024;
  fr=osc/r_counter; //r_counter=400; fr=5k;
  nh=fout/fr;
  n_counter=nh/p;
  a_counter=nh%p;  
}


void send_rdata()
{
  uchar i,j;
  
  en=1;
  _nop_();_nop_();_nop_();
  
  en=0;
  
  r_counter=r_counter<<2;
  lcmchr('r',0,0);
  
  for(i=0;i<14;i++)
  {
    clk=0;
    _nop_();_nop_();
    
    cdata=r_counter&0x8000;
    clk=1;
    j=cdata;
    lcmnxchr(j+0x30);
    r_counter=r_counter<<1;
  }
  
  clk=0;
  _nop_();
  
  cdata=1;
  _nop_();clk=1;_nop_();
  
  j=cdata;
  lcmnxchr(j+0x30);
  
  en=1;
  _nop_();
  
  en=0;
  delay_1ms(1);
}


void send_nadata()
{
  uchar i,j;
  ulong na,new_n,new_a;
  
  new_n=n_counter&0x03ff;
  new_n=new_n<<7;
  new_a=a_counter&0x7f;
  na=new_n+new_a;
  
  lcmchr('n',1,0);
  
  for(i=0;i<17;i++)
  {
    clk=0;
    _nop_();
    
    cdata=na&0x00010000;
    _nop_();
    
    clk=1;
    _nop_();
    
    j=cdata;
    lcmnxchr(j+0x30);
    
    //delay_1ms(2000);
    na=na<<1;
  }
  
  clk=0;
  _nop_();
  
  cdata=0;
  _nop_();
  
  clk=1;
  _nop_();
  
  
  j=cdata;
  lcmnxchr(j+0x30);
  
  en=1;
  _nop_();
  
  en=0;
  _nop_();
}


main()
{
  uint m,n=34000;
  
  p2_0=0;
  p2_1=0;
  p2_2=0;
  
  lcminit();
  lcmstr("cug pll fre syn!",0,0);
  mc145158(10240,64,n);
  send_rdata();
  
  //while(p2_1==0);
  send_nadata();
  
  while(1)
  {
    if(p2_0==1)
    {
      n=n+100;
      delay_1ms(100);
      
      lcmstr("fre: 34000 khz   ",1,0);
      mc145158(10240,64,n);
      send_rdata();
      
      //while(p2_1==0);
      send_nadata();
      lcmchr(m+0x30,1,15);
      
      m++;
      p2_0=0;
    }
    else if(p2_1==1)
    {
      n=n+200;
      delay_1ms(100);
      
      lcmstr("fre: 34000 khz   ",1,0);
      mc145158(10240,64,n);
      send_rdata();
      
      //while(p2_1==0);
      send_nadata();
      lcmchr(m+0x30,1,15);
      
      m++;
      p2_1=0;
    }
    else if(p2_2==1)
    {
      n=n+500;
      delay_1ms(100);
      
      lcmstr("fre: 33000 khz   ",1,0);
      mc145158(10240,64,n);
      send_rdata();
      
      //while(p2_1==0);
      send_nadata();
      lcmchr(m+0x30,1,15);
      
      m++;
      p2_2=0;
    }
    delay_1ms(100);    
  }
}
离线wb4916
发帖
213
只看该作者 3楼 发表于: 2009-12-03
看代码是asm版本的,大家/自己理解起来诸多不便,于是转换成c语言版本之后再理解了,利己达人!(上一楼的头文件)
注意:为了便于大家查看。所有的空格就转给不可见字符了。20 20 20 20 转 a1 a1 a1 a1
请大家下载附件中的代码编译,请勿直接复制!



//以下为液晶1602的显示程序(作为头文件调用)


#include "at89x52.h"
#include "intrins.h"


//==============特殊声明=====================
#define uint unsigned int
#define uchar unsigned char

//=============管脚定义=================
#define lcmdata p0

sbit lcmrs = p2^5;  //0-命令,1-数据
sbit lcmrw = p2^6;  //0-写lcm,1-读lcm
sbit lcme  = p2^7;  //下降沿有效

sbit bf = lcmdata^7;


//以下命令 lcmrs=0,lcmrw=0;
//lcmdata = b(00000001),清显示,光标复位到地址00h位置
//lcmdata = b(0000001x),光标复位,光标返回到地址00h
//lcmdata = b(000001[i/d]s),i/d=1,光标右移,i/d=0,左移;s:屏幕上所有文字是(s=1)否(s=0)左移或者右移
//lcmdata = b(00001dcb),d:控制整体显示的开(d=1)与关(d=0),c:控制光标的开(c=1)与关(c=0),b:控制光标是(b=1)否(b=0)闪烁
//lcmdata = b(0001[s/c][r/l]xx),s/c=1,移动光标和显示的文字, s/c=0,移动光标;r/l=1,右移,r/l=0,左移
//lcmdata = b(001[dl]nfxx),dl=0,4位总线,d7~d4,dl=1,8位总线;n=0,单行显示,n=1,双行显示;f=0,显示5x7的点阵字符,f=1,显示5x10的点阵字符
//lcmdata = b(01aaaaaa),字符发生器ram地址设置
//lcmdata = b(1aaaaaaa),ddram地址设置
//以下命令 lcmrs=0,lcmrw=1
//lcmdata = b([bf]aaaaaaa),bf=1,忙,bf=0,闲
//以下命令 lcmrs=1,lcmrw=0
//写数据
//以下命令 lcmrs=1,lcmrw=1
//读数据


//===============函数===============
lcminit();
lcmdelay();
lcmcon(char c);
lcmchr(char chr,char hang,char wei);
lcmnxchr(char chr);
lcmstr(char * str,char hang,char wei);


//================液晶初始化=============
lcminit()
{
  lcmcon(0x38); //00111000
  lcmcon(0x38);
  lcmcon(0x38);
  lcmcon(0x38);
  lcmcon(0x01); //00000001
  lcmcon(0x06); //00000110
  lcmcon(0x0c); //00001100
  
}


//============液晶显示忙等待==============
lcmdelay()
{
  while(1)
  {
    lcmdata = 0xff;
    lcmrs = 0;
    lcmrw = 1;
    lcme = 0;
    _nop_();
    lcme = 1;
    
    if(bf == 0)
    {
      break;
    }
  }
}


//===============液晶命令============
lcmcon(char c)
{
  lcmdata = c;
  lcmrs = 0;
  lcmrw = 0;
  lcme  = 0;
  lcmdelay();
  lcme  = 1;
}


//=========液晶显示lcmchr()==============
lcmchr(char chr,char hang,char wei)
{
  lcmcon(0x80+0x40*hang+wei);
  lcmdata = chr;
  lcmrs = 1;
  lcmrw = 0;
  lcme = 0;
  lcmdelay();
  lcme = 1;
}


//============液晶显示lcmnxchr()==========
lcmnxchr(char chr)
{
  lcmdata = chr;
  lcmrs = 1;
  lcmrw = 0;
  lcme = 0;
  lcmdelay();
  lcme = 1;
}


//==========液晶显示lcmpstr()=============
lcmstr(char *str,char hang,char wei)
{
  lcmcon(0x80+0x40*hang+wei);
  
  while(*str!='\0')
  {
    lcmdata = *str++;
    lcmrs = 1;
    lcmrw = 0;
    lcme = 0;
    lcmdelay();
    lcme = 1;
  }
}