| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2916 人关注过本帖
标题:向高手请教单片机atmega8的输入引脚寄存器PIN的使用
只看楼主 加入收藏
藏月亮
Rank: 1
等 级:新手上路
帖 子:7
专家分:2
注 册:2011-7-25
结帖率:100%
收藏
已结贴  问题点数:20 回复次数:13 
向高手请教单片机atmega8的输入引脚寄存器PIN的使用
我鼓捣了一个用atmega8控制的智能小车,想实现这样一个功能:在小车前头两侧各装了一根铁丝,就叫它触须吧,当小车前行时,如果触须遇到障碍物,它会调整方向,电原理图如下:
图片附件: 游客没有浏览图片的权限,请 登录注册

以下代码只是测试触须的接通是否正常:
#include <avr/robot.h>                      //机器人的标准头文件
#include <avr/usta.h>                     //串口头文件            
int PC0_state(void)                          //获取PC0口的状态                             
{
    return(PINC&0x01)?1:0;               //判断左触须是否遇到障碍物
}

int PC1_state(void)                          //获取PC1口的状态
{
    return (PINC&0x02)?1:0;                //判断右触须是否遇到障碍物

}
int main(void)
{
    usta_Init();                               //串口初始化
    printf ("program running");                //调试窗口显示一条信息
    while(1)
    {
        printf ("左边触须的状态:%d\n",PC0_state());
        printf ("   右边触须的状态:%d\n",PC1_state());
        delay_nms(100);               //延时100毫秒检查触须是否再次碰到障碍物                                 
     }
   
}

当俺写片实验时,触须状态显示都很正常,当俺用手压下触须时,状态显示低电平0,松开时显示高电平1,用万用表测量10K电阻两侧时,随着触须的状态变化,电阻上的电压也随着变化。但无论如何触动触须,220的电阻上测不到电压,也就是单片机PC0和PC1上无电流  流出,这样的话俺就纳闷,如果触须没有碰到,输入引脚寄存器PINC内应该是高电平1,碰到触须后,PINC内部就是低电平0,这时应该有电流, 那么220的电阻上就应该有电压,请高手指点,PINC&0x02 该如何去理解这条语句?俺是C语言新手,请说详细点,不胜感激,输入引脚寄存器PIN的工作原理是什么?
搜索更多相关主题的帖子: 小车 include 寄存器 return 
2012-11-18 12:49
藏月亮
Rank: 1
等 级:新手上路
帖 子:7
专家分:2
注 册:2011-7-25
收藏
得分:0 
怎么没人理俺?
2012-11-18 17:29
pauljames
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:千里冰封
威 望:9
帖 子:1555
专家分:10000
注 册:2011-5-8
收藏
得分:5 
你用AVR的单片机,并口的方向是要配置的;即使是MCS51的,也要输出1以后再读入。你直接去读是不可以的。

经常不在线不能及时回复短消息,如有c/单片机/运动控制/数据采集等方面的项目难题可加qq1921826084。
2012-11-18 17:41
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:5 
220欧的电阻上测不到电压是正常的(不是完全没有,但压降很小,你的万用表精度也不够)

一般单片机的输出功率很小,输出电流大概也就只能到十几毫安,引脚内部使用MOS电路,对外呈高阻态的。它对外只用于输出(接收)电平信号。

从你的图纸上看,你的触须是改变外电路对芯片的输入电平,引脚根据电平的变化做出相应的反馈。当触须没动时,开关打开,引脚处呈高电平;当触须被触动时,开关闭合220欧电阻一端接地,引脚处呈低电平。

开关打开时,PC引脚内部的MOS管电压被抬高,电阻上的压降很小,而且主要分配在10k电阻上,220上测不出电压。

开关闭合时,PC引脚内部的MOS管电压被拉低,这时220电阻上的压降依旧很小,也测不出。

PINC & 2 是在获取PC1引脚的电平状态。

重剑无锋,大巧不工
2012-11-18 18:14
embed_xuel
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:58
帖 子:3845
专家分:11385
注 册:2011-9-13
收藏
得分:0 
回复 4楼 beyondyf
全才啊

总有那身价贱的人给作业贴回复完整的代码
2012-11-18 18:17
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
回复 5楼 embed_xuel
呵呵,班门弄斧了,说错勿怪啊。我的本门专业是电气工程,随然针对的是大电压系统,但电路分析没有本质的差别,模电也是我的专业课。学艺不精,但略懂。

重剑无锋,大巧不工
2012-11-18 18:24
embed_xuel
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:58
帖 子:3845
专家分:11385
注 册:2011-9-13
收藏
得分:0 
硬件的知识都快忘光了,现在就会点C语言了,佩服兄弟,真心的

总有那身价贱的人给作业贴回复完整的代码
2012-11-18 18:28
青春无限
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江苏
等 级:贵宾
威 望:24
帖 子:3452
专家分:19340
注 册:2012-3-31
收藏
得分:5 
pinc&2,就是只取pc口的pc.1位
AVR与51不同,
51的输出输入是同一个寄存器
而AVR是分开的
pin是输入接收寄存器

学 会看代码…学习写程序…学会搞开发…我的目标!呵呵是不是说大话啊!!一切皆可能
2012-11-18 21:46
藏月亮
Rank: 1
等 级:新手上路
帖 子:7
专家分:2
注 册:2011-7-25
收藏
得分:0 
  首先感谢3  4  8楼老师的讲解,也感谢关注此贴的朋友。 对于  PINC&0x01   我是这样理解的,0x01  转换成二进制就是00000001  也就是屏蔽了前7位,只取  1  对应的pc0口,1对应着高电平,触须没有触动时,PINC存储的是高电平1,这样的话  PINC&0x01的值就是1, 当触须被触动时,PINC存储的是低电平0,PINC&0x01的值就是0,也不知道俺这样理解是否正确,还请 各位老师给与 指点。
  我只有高中文凭,因为伤着手了,在家病休,趁机会学C 语言,
 我用万用表测量了一下pc1与GND引脚之间的电压,触须不动时电压是5v,触动触须后,电压是0,

[ 本帖最后由 藏月亮 于 2012-11-19 10:09 编辑 ]
2012-11-19 09:41
藏月亮
Rank: 1
等 级:新手上路
帖 子:7
专家分:2
注 册:2011-7-25
收藏
得分:0 
和PINC&0x01有关的代码
下边这段代码是小车在行走到墙角处两根触须交替碰墙4次时做一个180度的转弯,逃离死角,在烧片实验时,两根触须碰到墙角,小车还是前行,手动实验也是如此,问题大概还是出在  PINC&0x01    PINC&0x02  这两个地方,请老师指点 ,应该如何修改?

#include <avr/robot.h>                   //小车的标准头文件
#include <avr/usta.h>                    //串口的头文件
int PC0_state(void)                    //获取PC0的状态
{
    return (PINC&0x01)?1:0;            // 判断左胡须是否遇到障碍物
}

int PC1_state(void)                    //获取PC1的状态
{
    return (PINC&0x02)?1:0;             // 判断右胡须是否遇到障碍物
}

void Forward(void)                    //声明一个前进子函数
{
    HIGH_PORTC3;                      //设置PC3输出高电平
    delay_nus(1700);                    //延时0.0017s
    LOW_PORTC3;                         //设置PC3输出低电平
    HIGH_PORTC2;                      //设置PC2输出高电平
    delay_nus(1300);                  //延时0.0013s
    LOW_PORTC2;                         //设置PC2输出低电平
    delay_nms(20);                     //延时20ms
}

void Left_Turn(void)                    //声明一个向左子函数
{
    for(uint16_t i=1;i<=26;i++)         /*声明定义16位无符号整型变量i*/
   {
        HIGH_PORTC3;               //设置PC3输出高电平
        delay_nus(1300);             //延时0.0013s
        LOW_PORTC3;                //设置PC3输出低电平
        HIGH_PORTC2;               //设置PC3输出高电平
        delay_nus(1300);            //延时0.0013s
        LOW_PORTC2;                    //设置PC2输出低电平
        delay_nms(20);                 //延时20ms
    }
}

void Right_Turn(void)                  //声明一个向右子函数
{
    for(uint16_t i=1;i<=26;i++)          /*声明定义16位无符号整型变量i*/
   {
        HIGH_PORTC3;               //设置PC3输出高电平
        delay_nus(1700);            //延时0.0017s
        LOW_PORTC3;                 //设置PC3输出低电平
        HIGH_PORTC2;                  //设置PC2输出高电平
        delay_nus(1700);               //延时0.0017s
        LOW_PORTC2;                     //设置PC2输出低电平
        delay_nms(20);                  //延时20ms
    }
}

void Backward(void)                      //声明一个向后子函数
{
    for(uint16_t i=1;i<=65;i++)             /*声明定义16位无符号整型变量i*/
    {
        HIGH_PORTC3;                     //设置PC3输出高电平
        delay_nus(1300);                  //延时0.0013s
        LOW_PORTC3;                      //设置PC3输出低电平
        HIGH_PORTC2;                     //设置PC2输出高电平
        delay_nus(1700);                     //延时0.0017s
        LOW_PORTC2;                     //设置PC2输出低电平
        delay_nms(20);                      //延时20ms
    }
}

int main(void)                           
{
    usta_Init();                          //串口初始化
    printf("Program Running!");             //在调试窗口显示一条信息
    SET_DDRD7;                             //设置PD7为输出口
    SET_DDRC3;                          //设置PC3为输出口
    SET_DDRC2;                             //设置PC2为输出口
   
    for(uint16_t counter=1;counter<=6000;counter++)           //开始/复位信号 蜂鸣器
    {
        HIGH_PORTD7;                             //设置PD7输出高电平
        delay_nus(166);                          //延时0.00016s
        LOW_PORTD7;                           //设置PD7输出低电平
        delay_nus(166);                        //延时0.00016s
     }
    int  old2=1;                            //整型变量初始化
    int  old3=0;                                   //整型变量初始化
    int counter=1;                            //整型变量初始化
   
    while(1)   
        if(PC0_state()!=PC1_state())                      //判断是否有一根胡须被触动
        {
            if((old2!=PC0_state())&&(old3!=PC1_state()))    //再次检查是否有一根胡须被触动
            {
                counter=counter+1;                                //胡须触动计数器加1
                old2=PC0_state();                               //交换变量值
                old3=PC1_state();                               //交换变量值
                if(counter>4)            // 如果发现胡须连续四次被触动,那么计数值置1,并且进行"U"型拐弯
                {
                    counter=1;                           //胡须触动计数器置1
                    Backward();                             //向后
                    Left_Turn();                             //向左
                    Left_Turn();                             //向左
                }               
            }
            else                                           //小车没有陷入墙角
                counter=1;                                     //胡须触动计数器置1        
        }
        if((PC0_state()==0)&&(PC1_state()==0))           //两个胡须同时检测到障碍物时,后退,再向左转180度
        {
            Backward();                                             //向后
            Left_Turn();                                                 //向左
            Left_Turn();                                              //向左
        }
        else if(PC0_state()==0)                              //左边胡须检测到障碍物时,后退,再向右转90度
        {
            Backward();                                         //向后
            Right_Turn();                                      //向右
        }
        else if(PC1_state()==0)                              //左边胡须检测到障碍物时,后退,再向左转90度
        {
            Backward();                                     //向后
            Left_Turn();                                       //向左
        }
        else                                                  //没有胡须检测到障碍物时,向前走
            Forward();                                         //向前
    }
}
2012-11-19 10:45
快速回复:向高手请教单片机atmega8的输入引脚寄存器PIN的使用
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.031171 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved