打印
[STM8]

关于发送串形数据的疑问

[复制链接]
2779|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiangfeizi|  楼主 | 2010-9-27 14:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机STM8S903K3,现在要用3个口线和TM1628进行通讯,实现显示的驱动和按键的扫描功能。其中一个口线为片选信号,一个口线为时钟信号,一个口线为串形数据的输入输出口。请问哪位大侠有没有该功能的C程序模板?能否发给小弟参考一下。另外本人的主时钟是内部HIS时钟8分频后为2M,指令周期为0.5us,而TM1628的工作频率为450K,那么在数据通讯的时候,为了保证时钟的同步,是否需要发送数据的时钟也确定为450K?如果要确定为450K的话,感觉速度太快,每发送一位数据不能超过2.2US,不能多于4条指令,很是麻烦,我是不是需要再调快主时钟??请各位大侠不吝指教!
沙发
pzhd52| | 2010-10-15 17:21 | 只看该作者
问题解决没?分享一下

使用特权

评论回复
板凳
xiangfeizi|  楼主 | 2010-10-15 18:03 | 只看该作者
还没有,最近在调前面的一些功能。下周要把这个功能调好。到时候再分享哈。

使用特权

评论回复
地板
pzhd52| | 2010-10-20 09:22 | 只看该作者
你的串行数据口如何配置为输入输出的

使用特权

评论回复
5
xiangfeizi|  楼主 | 2010-10-21 08:43 | 只看该作者
4# pzhd52
现在显示程序已经写了部分,但是点不亮,很是郁闷,把程序贴出来,请大家指教。
其中PF4为片选信号,PA3为时钟信号,PB7为数据线,三个口线都采用推挽输出。

uchar show_led[14]={0xa8,0x01,0x6f,0x01,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00};//要发送的数据

uchar tm1628_senddata(uchar wr_data)//写数据子函数
{

uchar flag_data;
  PF_ODR&=0xef; //片选给低电平;
  for(ii=0;ii<8;ii++)
  {
  PA_ODR&=0xf7;//时钟信号置低
  flag_data=wr_data&&0x01;//发送的数据为wr_data的低位
  if(flag_data==0)
  PB_ODR&=0x7f;
  else
  PB_ODR|=0x80;
   wr_data>>=1;//将数据右移一位;
  PA_ODR|=0x08;//时钟信号置高
}
}

void display_tm1628(void)//显示程序
{
  PF_ODR|=0x10;
  PA_ODR|=0x08;
  PB_ODR|=0x80;
  tm1628_senddata(0x03);//显示模式设置,设置为7个GRID,10个SEG
        PF_ODR|=0x10;
  tm1628_senddata(0x40);//写数据到显示寄存器,采用地址自动加一
  PF_ODR|=0x10;
  tm1628_senddata(0xc0);//显示寄存器的00H单元开始
  for(hh=0;hh<14;hh++)
  {   
   tm1628_senddata(show_led[hh]);//给显示寄存器送数据,
   }
  PF_ODR|=0x10;
  tm1628_senddata(0x8b);//显示控制参数,点亮数码屏幕,亮度可以通过改变低三位调节       
}

main()
{
       
  _asm("sim");  
  clock_inti();
  io_inti();
        _asm("rim");
        timer6_50us();
   while(1)
        {
                 time_flag();
                 
                 // ad_equel_value();
                //ad_alarm_judge();
                // songsi_read();//读调节送丝速度的电位器的AD
                //ad_pot1_read();//读调节PWM电位器的AD值
                  //jiaozhiliu_read();//读调节交直流的电位器的AD值
                  //beef_deal();
                 //led_deal();
                 //PB_ODR|=0x20;
     display_tm1628();
                 //PF_ODR|=0x10;
                 //PA_ODR|=0x08;
                 //PB_ODR|=0x80;
                // PF_ODR&=0xef;
                 //PA_ODR&=0xf7;
                 //PB_ODR&=0x7f;                       
        }

}

使用特权

评论回复
6
jgphu| | 2010-10-21 17:57 | 只看该作者
:)

使用特权

评论回复
7
yybj| | 2010-10-21 18:40 | 只看该作者
为啥点不亮,大侠给点评一下

使用特权

评论回复
8
xiangfeizi|  楼主 | 2010-10-22 14:29 | 只看该作者
用示波器看了下波形,好象完全不对,郁闷啊!

使用特权

评论回复
9
xiangfeizi|  楼主 | 2010-10-22 15:57 | 只看该作者
结合示波器和仿真的变量观察,终于把问题找到了。汗啊,还是一些基本概念没弄明白啊。更改的内容是:
1。发送的数据与0X01做与运算时,写错了。原来为:flag_data=wr_data&&0x01;应该改为:flag_data=wr_data&0x01; 双与是关系运算,单与才是位运算。错在基本概念上,郁闷!
2.忘记清flag_data标记了,给PB7置位后应该清标记。语句改为:
if(flag_data==0)
  PB_ODR&=0x7f;
  else
{
    PB_ODR|=0x80;
   flag_data=0;
}

使用特权

评论回复
10
pzhd52| | 2010-10-26 22:22 | 只看该作者
兄弟我最近也做这样一个项目我的代码如下:
void indate(unsigned char p)
{unsigned int i;
PC_ODR&=0XDF;       //保证STB=0,程序不依赖于端口之前的状态
for(i=0;i<8;i++)
{
         PC_ODR&=0XEF;
         if(p&0X01!=0)
         {
                 PC_ODR|=0X01;   //需要传送的数据低位为“1”,则把DIO置1
          }
         else
                {
                 PC_ODR|=0XFE;   //需要传送的数据低位为“0”,则把DIO清0
          }
           PC_ODR|=0X01;   //送时钟的上升沿
         p>>1;             //准备送下一个bit
}
}                    //送完一个字节退出循
void display(unsigned char disa)
{unsigned int i;      //控制本次需要传输多少字节显示
PC_ODR|=0X38;        //通讯开始前通讯端口全部初始化为1
indate(0x40);        //写数据到显示寄存器,采用地址自动加1
PC_ODR|=0X20;        //数据设置命令传输完后需要将“STB”置1
indate(0xC0);        //显示寄存器的地址从00H开始
for(i=0;i<14;i++)    //传输14个字节到TM1629C
   {
           indate(disa);   
        //在连续传输数据的过程中,“STB”一直保持为零
         }
PC_ODR=0X20;         //传完所有数据后将STB置1
indate(disconmode);  //传显示控制命令
PC_ODR=0X20;         //传完显示控制命令后将STB置1
}
main()
{_asm("rim\n")                //打开系统总中断
GPIO_init()                  //gpio初始化
TIM4_init()                  //TIM4初始化
PC_ODR|=0X38;                //串行接口初始化
indate(dissetmode);          //设置显示模式
display(led_ql);             //开机全亮
delay(10);
while(1)
  {
         if(k1=0x08)          //如果K1按下     
   display(led_k1);
   if(k1=0x80)               //如果K2按下
         display(led_k2);
   if(k2=0x08)               //如果K3按下
   display(led_k3);
         if(k2=0x80)         //如果K4按下
   display(led_k4);
   if(k3=0x08)               //如果K5按下
         display(led_k5);
   if(k3=0x80)               //如果K6按下
         display(led_k6);
   if(k4=0x08)               //如果K7按下
   display(led_k7);
   if(k4=0x80)               //如果K8按下
   display(led_k8);
         }
}

使用特权

评论回复
11
pzhd52| | 2010-10-26 22:27 | 只看该作者
TM1629C一次只能传14BYTE,可我每次想传16BYTE。是否要用一次自动加1模式和2次固定地址模式才能完成。
还有就是我还要其中的一些LED闪烁杂控制?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

62

帖子

0

粉丝