amobbs.com 阿莫电子技术论坛

标题: 气死我了,74hc595的驱动函数调了2天,它就是不显示,位选都成功了,就是595的驱动函数有问 [打印本页]

作者: xtaens    时间: 2010-10-17 16:58
标题: 气死我了,74hc595的驱动函数调了2天,它就是不显示,位选都成功了,就是595的驱动函数有问
编译软件ICC6.31a
m48单片机
位选采用138译码器实现,程序是没问题的

#include <iom48v.h>
#include <macros.h>
#include ".\head\ICC_AVRPORTBit.h"
#include ".\head\Delay.h"

#define uint8 unsigned char

//74HC595的端口定义
#define Hc595_data PORTB_PB2
#define Hc595_clk  PORTB_PB1
#define Hc595_stcp PORTB_PB0  //片选

//74HC138的端口定义
#define Hc138_A0  PORTB_PB3
#define Hc138_A1  PORTB_PB4
#define Hc138_A2  PORTB_PB5

const uint8 LedDisplayCode[]=
{
    0xC0,/*0*/
    0xF9,/*1*/
    0xA4,/*2*/
    0xB0,/*3*/
    0x99,/*4*/
    0x92,/*5*/
    0x82,/*6*/
    0xF8,/*7*/
    0x80,/*8*/
    0x90,/*9*/
    0x88,/*A*/
    0x83,/*b*/
    0xC6,/*C*/
    0xA1,/*d*/
    0x86,/*E*/
    0x8E,/*F*/
    0xBF,/*-*/
};

void Hc595_send_byte(unsigned char byte)
{
     unsigned char i;
     for(i=0;i<8;i++)
     {
         
          Hc595_data=byte&(0x80>>i);
          Hc595_clk=0;
          Delay_nus(5);
          Hc595_clk=1;         
     }
     Delay_nus(5);
     Hc595_clk=0;
     Delay_nus(5);
     Hc595_stcp=0;
     Delay_nus(5);
     Hc595_stcp=1;
}
/*
void Hc595_send_int(uint8 data)
{
     unsigned char int_l,int_h;
     int_l=data;    //取低4位
     int_h=data>>4;      //取高4位
     Hc595_send_byte(int_l);
     Hc595_send_byte(int_h);
     Hc595_stcp=1;
     Hc595_stcp=0;
}*/

void Select_LED_Bit(uint8 Bit_Num)
{
    switch(Bit_Num)
    {
        case 0:
               Hc138_A2=0;
               Hc138_A1=0;
               Hc138_A0=0;
               break;
        case 1:
               Hc138_A2=0;
               Hc138_A1=0;
               Hc138_A0=1;
               break;
        case 2:
               Hc138_A2=0;
               Hc138_A1=1;
               Hc138_A0=0;
               break;
        case 3:
               Hc138_A2=0;
               Hc138_A1=1;
               Hc138_A0=1;
               break;
        case 4:
               Hc138_A2=1;
               Hc138_A1=0;
               Hc138_A0=0;
               break;
        case 5:
               Hc138_A2=1;
               Hc138_A1=0;
               Hc138_A0=1;
               break;
       case 6:
               Hc138_A2=1;
               Hc138_A1=1;
               Hc138_A0=0;
               break;
       case 7:
               Hc138_A2=1;
               Hc138_A1=1;
               Hc138_A0=1;
               break;               
    }
}
void main()
{
    uint8 i;
    DDRB=0XFF;
    PORTB=0XFF;
        while (1)
        {
                //for(i=0;i<8;i++)
        //{
             Select_LED_Bit(7);
             //Hc595_send_int(LedDisplayCode);
             Hc595_send_byte(0x86);            
             //Delay_nms(100);           
       // }
        }
}
作者: xiaobendan    时间: 2010-10-17 17:26
都这年代了,还研究M48?我们都改51了
既然程序没有问题,贴出来看个屁啊,还是把电路也贴出来看看吧
作者: xtaens    时间: 2010-10-17 18:57
回复【1楼】xiaobendan 仲跻东
-----------------------------------------------------------------------

1、说话太不文明了

2、51也8块以上,48也10块以上,性能却差很多,而且48也不是不可能不降了
作者: bj-stm8    时间: 2010-10-17 19:41
STC的貌似4元起
作者: linyu0395    时间: 2010-10-17 20:24
mega88和48似乎降价了哦   项目上之前没办法直接全部替换掉  前天又购买了几百片  一片11块  应该降价了不少了
作者: 19871212    时间: 2010-10-17 20:33
早就  STC 啦!   程序不想看, 你还是看看时序,还有你的电路好了。。。。
作者: xtaens    时间: 2010-10-17 20:45
大哥们我的程序问题在哪里啊?别先讨论钱的问题啊

我刚仿真了,595的并行输出始终是高电平,这是怎么回事啊
作者: rainyss    时间: 2010-10-17 21:42
for(i=0;i<8;i++)
     {
         
          Hc595_data=byte&(0x80>>i);
          Hc595_clk=0;
          Delay_nus(5);  
          Hc595_clk=1;           
     }


你这是构造下降沿.另外你的电路图呢?
作者: wajlh    时间: 2010-10-17 21:49
595时序对么?
作者: wkman    时间: 2010-10-17 22:15
看看这个吧,很简单的东西。。。

74HC595驱动程序2例
程 序 匠 人 发表于 2005-11-10 20:37:00  阅读全文(8125) | 回复(0) | 引用通告(4) | 编辑


给个74HC595的"慢动作"
  
  
void WriteSIOByte(unsigned char val)
{
unsigned char i;
  ACC = val;
  for (i = 8; i > 0; i --) {
    SRCLK = 0;//拉低74HC595时钟
    _rrca_();//右移一位数据
    SER = CY;//发送74HC595一位串行数据
    SRCLK = 1;//拉高74HC595时钟
    _nop_();//延时
  }
  SER = 1;//释放数据总线
//以下3条指令若在多字节时,应该移入多字节全发送完后在执行此3条指令
  RCLK = 0;
  _nop_();//延时
  RCLK = 1;//打入并行数据
}



74ls595"速射"
  
  
hotpower

  for(i = 0; i < buffsize; i ++){
    SBUF = siobuff;
    while(TI == 0);
    TI = 0;
  }
  RCLK = 0;
  _nop_();//延时
  RCLK = 1;//打入并行数据
作者: xtaens    时间: 2010-10-18 13:42
回复【7楼】rainyss
-----------------------------------------------------------------------


(原文件名:1.jpg)


(原文件名:2.jpg)
作者: rainyss    时间: 2010-10-18 20:13
回复【10楼】xtaens
-----------------------------------------------------------------------

看不清.看我的吧.


(原文件名:无标题.gif)
作者: xtaens    时间: 2010-10-18 21:49
回复【11楼】rainyss
-----------------------------------------------------------------------

1、电路图是没有问题的,他是一个开发版原理图
2、请问:
for(i=0;i<8;i++)  
     {  
           
          Hc595_data=byte&(0x80>>i);  
          Hc595_clk=0;   
          Hc595_clk=1;            
     }
Hc595_data 的值应该只有0和1两个值,但是假如0x40&0x50=0x40, Hc595_data=0x40;
后Hc595_data的值是0x40呢还是别的数呢(如为1),我的编译软件为ICC6.31a,Hc595_data的值与编译软件有关系吗

谢谢啊
作者: rainyss    时间: 2010-10-19 00:22
Hc595_clk=0;   
for(i=0;i<8;i++)   
{   
            
     Hc595_data=byte&(0x80>>i);   
     Hc595_clk=1;            
     Hc595_clk=0;   
}

还有12脚HCLK和13脚OE你都处理没有?
作者: xtaens    时间: 2010-10-19 16:32
1、13脚我是接地了的
2、12脚的操作在下面函数的for循环后也是处理的了

void Hc595_send_byte(unsigned char byte)
{
     unsigned char i;
     for(i=0;i<8;i++)
     {
         
          Hc595_data=byte&(0x80>>i);
          Hc595_clk=0;
          Delay_nus(5);  
          Hc595_clk=1;           
     }
     Delay_nus(5);  
     Hc595_clk=0;
     Delay_nus(5);  
     Hc595_STCp=0;
     Delay_nus(5);  
     Hc595_STCp=1;
}
作者: xtaens    时间: 2010-10-19 16:33
回复【13楼】rainyss
-----------------------------------------------------------------------

Hc595_data=byte&(0x80>>i);
这句话是参考马朝老师354页的写法改的,不知改的正确与否?????
作者: lininglive    时间: 2010-10-19 17:00
void Hc595_send_byte(unsigned char byte)
{
     unsigned char i;
     unsigned char shift=0x80;
     for(i=0;i<8;i++)
     {
                 Hc595_clk=0;
                 
          if(byte&shift)                 
          {Hc595_data=1;}
          else
          {Hc595_data=0;}
                    
          Hc595_clk=1;
          shift>>=1;           
     }
     Delay_nus(5);  
     Hc595_clk=0;
     Delay_nus(5);  
     Hc595_STCp=0;
     Delay_nus(5);  
     Hc595_STCp=1;
}
你可以这样写试试 感觉你的那个函数有问题,还有就是把延时加大 试试,另一个就是查查 并口数据出使能的地方是不是时序配合有问题。
作者: lusson    时间: 2010-10-19 17:13
我一直用的时候常态SCK和RCK都是低电平,改成常态高电平时有问题,后面没有去研究了
作者: rainyss    时间: 2010-10-19 20:21
Hc595_data=byte&(0x80>>i);  
          Hc595_clk=0;  
          Delay_nus(5);   
          Hc595_clk=1;      


这种时序个人认为是不妥的,最好是产生上升沿后返回低电平.也许各人习惯不同吧.
作者: xtaens    时间: 2010-10-19 21:43
问题终于找出来了:
原来是Hc595_data=byte&(0x80>>i)在作怪,改成
if(byte&0x80)
     Hc595_data=1;
else
     Hc595_data=0;

就可以了,下面是全部的源代码,其中去掉延时程序也跑得很happy。

思考:Hc595_data=byte&(0x80>>i)在不同的编译软件上的结果是不是相同的呢(如马朝老师写的那种写法,软件为cvavr)
结论:以后为了万无一失还是写成这样吧,防止不同的编译器对他的理解不同
if(byte&0x80)
     Hc595_data=1;
else
     Hc595_data=0;
以上是我的观点,正确与否请大家指正


#include <iom48v.h>
#include <macros.h>
#include ".\head\ICC_AVRPORTBit.h"
#include ".\head\Delay.h"

#define uint8 unsigned char

//74HC595的端口定义
#define Hc595_data PORTB_PB2
#define Hc595_clk  PORTB_PB1
#define Hc595_stcp PORTB_PB0  //片选

//74HC138的端口定义
#define Hc138_A0  PORTB_PB3
#define Hc138_A1  PORTB_PB4
#define Hc138_A2  PORTB_PB5

const uint8 LedDisplayCode[]=
{
    0xC0,/*0*/
    0xF9,/*1*/
    0xA4,/*2*/
    0xB0,/*3*/
    0x99,/*4*/
    0x92,/*5*/
    0x82,/*6*/
    0xF8,/*7*/
    0x80,/*8*/
    0x90,/*9*/
    0x88,/*A*/
    0x83,/*b*/
    0xC6,/*C*/
    0xA1,/*d*/
    0x86,/*E*/
    0x8E,/*F*/
    0xBF,/*-*/
};

void Hc595_send_byte(unsigned char byte)
{
     unsigned char i;
     for(i=0;i<8;i++)
     {
          if(byte&0x80)
               Hc595_data=1;
          else
               Hc595_data=0;
          //Hc595_data=byte&(0x80>>i);//不知道这句话为什么不行
          byte <<=1;
          Hc595_clk=0;
          Hc595_clk=1;     
     }
     Hc595_stcp=0;
     Hc595_stcp=1;

}

/*
void Hc595_send_int(uint8 data)
{
     unsigned char int_l,int_h;
     int_l=data;    //取低4位
     int_h=data>>4;      //取高4位
     Hc595_send_byte(int_l);
     Hc595_send_byte(int_h);
     Hc595_stcp=1;
     Hc595_stcp=0;
}*/

void Select_LED_Bit(uint8 Bit_Num)
{
    switch(Bit_Num)
    {
        case 0:
               Hc138_A2=0;
               Hc138_A1=0;
               Hc138_A0=0;
               break;
        case 1:
               Hc138_A2=0;
               Hc138_A1=0;
               Hc138_A0=1;
               break;
        case 2:
               Hc138_A2=0;
               Hc138_A1=1;
               Hc138_A0=0;
               break;
        case 3:
               Hc138_A2=0;
               Hc138_A1=1;
               Hc138_A0=1;
               break;
        case 4:
               Hc138_A2=1;
               Hc138_A1=0;
               Hc138_A0=0;
               break;
        case 5:
               Hc138_A2=1;
               Hc138_A1=0;
               Hc138_A0=1;
               break;
       case 6:
               Hc138_A2=1;
               Hc138_A1=1;
               Hc138_A0=0;
               break;
       case 7:
               Hc138_A2=1;
               Hc138_A1=1;
               Hc138_A0=1;
               break;               
    }
}
void main()
{
    uint8 i;
    DDRB=0XFF;
    PORTB=0XFF;
    while (1)
   {
        for(i=0;i<8;i++)
        {
             Select_LED_Bit(i);
             Hc595_send_byte(LedDisplayCode);           
             Delay_nms(300);           
        }
    }
}
作者: taocongrong    时间: 2011-12-29 16:59
支持 有时候调程序要挑好几天了呢!!!很正常!
作者: LKingK    时间: 2012-3-26 12:50
mark  一下下
作者: cos    时间: 2012-6-6 12:52
#include <iom8.h>
#include "SPI595.h"

__flash unsigned char Table[]={  
                0x03,  //"0"
                0x9F,  //"1"
                0x25,  //"2"
                0x0D,  //"3"
                0x99,  //"4"
                0x49,  //"5"
                0x41,  //"6"
                0x1F,  //"7"
                0x01,  //"8"
                0x09,  //"9"
                0x11,  //"A"
                0xC1,  //"B"
                0x63,  //"C"
                0x85,  //"D"
                0x61,  //"E"
                0x71,  //"F"
                0x91,  //"H"
                0xE3,  //"L"
                0x13,  //"n"
                0x83,  //"u"
                0x31,  //"P"
                0xC5,  //"o"
                0xFD,  //"-"
                0xFF,  //close
};

__flash unsigned char Bit_Tab[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};  //NPN

unsigned char DisBuffer[8] = {1,2,3,4,5,6,7,8};

#pragma vector = SPI_STC_vect
__interrupt void SPI_isr(void)
{
        volatile static unsigned char Loop=0,LedCycle=0;
        _CLI();
        if(Loop == 0)
        {
                SPDR = Bit_Tab[LedCycle];
                Loop = 1;
        }
        else
        {
                if(Loop == 1)
                {
                        SPDR = Table[DisBuffer[LedCycle]];
                        Loop = 3;
                }
                else
                {
                        Loop = 0;
                        ST_CLKHigh;
                        _NOP();
                        _NOP();
                        _NOP();
                        _NOP();
                        ST_CLKLow;
                        SPDR = 0x00;
                        LedCycle++;
                        LedCycle &= 0x7;
                }
        }
        _SEI();
}

void SPI_MasterInit(void)
{
        PORTB|= (1<<PB2) | (1<<PB5) | (1<<PB7);
        DDRB |= (1<<PB2) | (1<<PB5) | (1<<PB7);
        // SPI initialization
        // SPI Type: Master
        // SPI Clock Rate: 2*2000.000 kHz
        // SPI Clock Phase: Cycle Start
        // SPI Clock Polarity: Low
        // SPI Data Order: MSB First
        SPCR=0xD1;
        SPSR=0x00;
        _NOP();
        _NOP();
        SPDR = 0xff;
}
在中断里调 用的,用M8

作者: millwood0    时间: 2012-6-8 08:32
Hc595_data=byte&(0x80>>i)在不同的编译软件上的结果是不是相同的呢



because assigning a non-bit value to a bit type is undefined in C.

writing it explicitly as you did is the right way to go.





欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/) Powered by Discuz! X3.4