你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32读取两片74hc165d数据,总是读不对,求指教?

[复制链接]
月霜寒 提问时间:2017-3-17 09:16 /
unsigned char i;
  ADDR_SW_Data = 0;
  GPIO_ResetBits(GPIOC, 2);//clock_en ´ò¿ª165ѡͨ¶Ë
  GPIO_ResetBits(GPIOC, 1);//PL  //ÔËÐÐÊý¾Ý¼ÆÈë165
  delay_ms(1);
  GPIO_SetBits(GPIOC, 1);//PL //ÔÊÐíÊý¾ÝÒÆÎ»
  delay_ms(1);
  for(i=0;i<16;i++)  //¶Á16´ÎÊý¾Ý
  {
    GPIO_ResetBits(GPIOC, 0);//clock
    delay_ms(1);
   
    ADDR_SW_Data = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3) | (ADDR_SW_Data<<1);//¶ÁÊäÈëÊý¾Ýλ  
   
    GPIO_SetBits(GPIOC, 0);//clock
    delay_ms(1);
  }
  GPIO_SetBits(GPIOC, 2);//clock_en //¹Ø±Õ165ѡͨ¶Ë
  GPIO_ResetBits(GPIOC,1);//PL  //ÔËÐÐÊý¾Ý¼ÆÈë165
  
  ADDR_SW_Data  =  ~ADDR_SW_Data;      //²¦Â뿪¹ØÈ¡·´
收藏 3 评论21 发布时间:2017-3-17 09:16

举报

21个回答
月霜寒 回答时间:2017-4-5 16:34:38
#include "74HC165D.h"
#include "delay.h"
#include "485test.h"

unsigned int ADDR_SW_Data,HC=0;

void ADDR_SW_Init(void)//74HC165D各引脚初始化
{
        GPIO_InitTypeDef                 ADDR_SW_GPIO_InitStructure;
        /* GPIOD Periph clock enable */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);         //
        /* Configure zoom and focus pins in output pushpull mode */
        ADDR_SW_GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;//0:clock;1L;2:clock_en
        GPIO_SetBits(GPIOC, GPIO_Pin_0);//clock
        GPIO_SetBits(GPIOC, GPIO_Pin_1);//PL
        GPIO_SetBits(GPIOC, GPIO_Pin_2);//clock_en

        ADDR_SW_GPIO_InitStructure.GPIO_Speed         = GPIO_Speed_50MHz;
        ADDR_SW_GPIO_InitStructure.GPIO_Mode                 = GPIO_Mode_Out_PP; //推挽输出
        GPIO_Init(GPIOC, &ADDR_SW_GPIO_InitStructure);

        /* Configure SPI1 pins: MISO and MOSI */
        ADDR_SW_GPIO_InitStructure.GPIO_Pin         = GPIO_Pin_3;//DATA_OUT       
        ADDR_SW_GPIO_InitStructure.GPIO_Mode         = GPIO_Mode_IN_FLOATING;                //浮空输入
        GPIO_Init(GPIOC, &ADDR_SW_GPIO_InitStructure);       
}

void read_ADDR_SW(void)//读取74HC165D函数值
{
                unsigned char i;
                ADDR_SW_Data        =        0;

                GPIO_ResetBits(GPIOC, GPIO_Pin_2);//clock_en                //打开165选通端
                GPIO_ResetBits(GPIOC, GPIO_Pin_1);        //运行数据计入165
                delay_ms(1);
                GPIO_SetBits(GPIOC, GPIO_Pin_1);        //允许数据移位
       
                for(i=0;i<16;i++)                //读16次数据
                {
                                GPIO_ResetBits(GPIOC, GPIO_Pin_0);
                                delay_ms(1);
                                ADDR_SW_Data        =        GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3)        | (ADDR_SW_Data<<1);                       
                                GPIO_SetBits(GPIOC, GPIO_Pin_0);
                                delay_ms(1);
                }

                GPIO_SetBits(GPIOC, GPIO_Pin_2);        //关闭165选通端
                GPIO_ResetBits(GPIOC, GPIO_Pin_1);        //运行数据计入165
               
                ADDR_SW_Data                =                ~ADDR_SW_Data;                                                //拨码开关取反
                //PT_currentaddr        =                ADDR_SW_Data        &        0x00ff;                //拨码开关低8位为地址
               
                switch((ADDR_SW_Data        >>        8)        &        0x0003)                                //拨码开关高8位为波特率设置,低2位为波特率设置位
    {
        case 0x0000 :
        {
                                                //current_BautRate                         = 2400;
                                                USART_SendData(USART1, 1);
                                                while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//检测发送状态寄存器
                                                break ;
                                }
        case 0x0001 :
        {
                                                //current_BautRate                         = 4800;
                                                USART_SendData(USART1, 2);
                                                while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//检测发送状态寄存器
                                                break ;
                                }
        case 0x0002 :
        {
                                                //current_BautRate                         = 9600;
                                                USART_SendData(USART1,3);
                                                while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//检测发送状态寄存器
                                                break ;
                                }
        case 0x0003 :
        {
                                                //current_BautRate                         = 19200;
                                                USART_SendData(USART1, 4);
                                                while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//检测发送状态寄存器
                                                break ;
                                }
        default :       
                                                //current_BautRate                         = 2400;       
                                        {USART_SendData(USART1, 1);
                                        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//检测发送状态寄存器
                                        }
        break ;
                }
               
}



月霜寒 回答时间:2017-3-17 09:17:18
这是初始化:
GPIO_InitTypeDef                 ADDR_SW_GPIO_InitStructure;
        /* GPIOD Periph clock enable */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);         //
        /* Configure zoom and focus pins in output pushpull mode */
        ADDR_SW_GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;//0:clock;1L;2:clock_en
        GPIO_SetBits(GPIOC, 0);//clock
        GPIO_SetBits(GPIOC, 1);//PL
        GPIO_SetBits(GPIOC, 2);//clock_en

        ADDR_SW_GPIO_InitStructure.GPIO_Speed         = GPIO_Speed_50MHz;
        ADDR_SW_GPIO_InitStructure.GPIO_Mode                 = GPIO_Mode_Out_PP; //ÍÆÍìÊä³ö
        GPIO_Init(GPIOC, &ADDR_SW_GPIO_InitStructure);

        /* Configure SPI1 pins: MISO and MOSI */
        ADDR_SW_GPIO_InitStructure.GPIO_Pin         = GPIO_Pin_3;//DATA_OUT       
        ADDR_SW_GPIO_InitStructure.GPIO_Mode         = GPIO_Mode_IN_FLOATING;                //¸¡¿ÕÊäÈë
        GPIO_Init(GPIOC, &ADDR_SW_GPIO_InitStructure);       
七哥 回答时间:2017-4-5 16:12:43
本帖最后由 toofree 于 2017-4-5 16:14 编辑

  1. unsigned char i;
  2.   ADDR_SW_Data = 0;
  3.   GPIO_ResetBits(GPIOC, 2); // clock_en,165时钟消禁止位,1禁止,0使能。使能
  4.   GPIO_ResetBits(GPIOC, 1); // PL,165移位/加载位,1移位,0加载。加载
  5.   delay_ms(1);
  6.   GPIO_SetBits(GPIOC, 1);    //PL,加载并行数据
  7.   delay_ms(1);
  8.   for(i=0;i<16;i++)  //16次循环读取
  9.   {
  10.     GPIO_ResetBits(GPIOC, 0);//clock
  11.     delay_us(10);
  12.     GPIO_SetBits(GPIOC, 0);   //clock,上升沿,D触发器打数
  13.     delay_us(5);   //这里为什么要加个延时呢?D触发器打数到稳定需要时间;STM32的IO管脚接收到数据,到数据稳定也需要时间。不见得非得是5us,但必须有
  14.     ADDR_SW_Data = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3) | (ADDR_SW_Data<<1); //之前数据左移1位,加上读取到的最低位
  15.     delay_us(5);  //补上5us,凑出20us,50%占空比

  16.   }
  17.   GPIO_SetBits(GPIOC, 2);   //clock_en,禁止时钟
  18.   GPIO_ResetBits(GPIOC,1);//PL,加载并行数据
复制代码

wenyangzeng 回答时间:2017-4-5 07:32:17
本帖最后由 wenyangzeng 于 2017-4-5 10:10 编辑

这个74HC165是串行接收,每次只读入1Bit,,读出后要马上移一位
for(i=0;i<16;i++)
{
GPIO_ResetBits(GPIOC, 0);
if( GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_3)
  GPIO_SetBits( ADDR_SW_Data, i);//先前变量弄错了
else
GPIO_ResetBits( ADDR_SW_Data, i);
GPIO_SetBits(GPIOC, 0);
}

补充一点:2只74HC165硬件还需要进行级连,否则只能8位8位的分别读其中1只。







评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

zhjb1 回答时间:2017-4-5 08:03:37
“板凳”那一页的代码缺少移位语句,数据只是LSB的1bit。看看是吗?
无薪税绵 回答时间:2017-4-5 08:23:36
检测口试试使用GPIO_Mode_IPU上拉输入,不要用浮空。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

小小超 回答时间:2017-4-5 08:27:04
ADDR_SW_Data = 0;   没定义数据类型??   16位数据用 uchar 应该会出错吧。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

wenyangzeng 回答时间:2017-4-5 09:51:59
本帖最后由 wenyangzeng 于 2017-4-5 10:09 编辑
zhjb1 发表于 2017-4-5 08:03
“板凳”那一页的代码缺少移位语句,数据只是LSB的1bit。看看是吗?

GPIO_SetBits( ADDR_SW_Data, i);//先前变量弄错了
else
GPIO_ResetBits( ADDR_SW_Data, i);
i已经在移位了,74HC165自己已经根据时钟在移动其并行端口的数据到串行输出端了。

cldym 回答时间:2017-4-5 11:22:38
检测口试试使用GPIO_Mode_IPU上拉输入,不要用浮空

点评

少灌水  发表于 2017-4-11 10:55
donatello1996 回答时间:2017-4-5 13:19:05
先试试驱动一片165行不行,一片能行再驱动两片165

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

七哥 回答时间:2017-4-5 14:44:11
wenyangzeng 发表于 2017-4-5 07:32
这个74HC165是串行接收,每次只读入1Bit,,读出后要马上移一位
for(i=0;i

你这个应该用上升沿或下降沿读取吧,你用电平肯定不行呀,而且中间没有延时,循环太快太快了。你循环结束了,一个位还没完呢。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

wenyangzeng 回答时间:2017-4-5 14:53:35
本帖最后由 wenyangzeng 于 2017-4-5 14:58 编辑
toofree 发表于 2017-4-5 14:44
你这个应该用上升沿或下降沿读取吧,你用电平肯定不行呀,而且中间没有延时,循环太快太快了。你循环结束 ...

按照你例程每接收1个bit延时1毫秒,接收1个字节就需要8毫秒,怎么受得了?如果不可靠,顶多在时钟沿到来之后加1-2个NOP足够矣。
纳秒级的呀:
HC165.png

中山无雪 回答时间:2017-4-5 14:56:54
为何不用上升沿/下降沿中断触发方式读取???

曾做过测试,使用电平方式特别容易受干扰,而是用上升沿/下降沿触发方式则可靠得多

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

七哥 回答时间:2017-4-5 15:57:07
wenyangzeng 发表于 2017-4-5 14:53
按照你例程每接收1个bit延时1毫秒,接收1个字节就需要8毫秒,怎么受得了?如果不可靠,顶多在时钟沿到来之 ...

不好意,看错了。以为是楼主的帖子,被程序给误导了。
七哥 回答时间:2017-4-5 15:58:42
楼主,把程序注释弄成能显示的字符吧,这乱码猜不到是什么意思。或者发一个原理图。
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版