100个io,单片机的io口满足不了怎么办

如何将单片机32个IO口拓展为64个双向输入输出口_单片机吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:82,399贴子:
如何将单片机32个IO口拓展为64个双向输入输出口收藏
要求能双向输入输出,怎么设计电路?回答的详细还会再加分。谢啦!!!
我觉得好像不行,求科普
换单片机最简单。。。
74hc595 74hc165 二极管
找一下i/o口扩展芯片
用若干74LS244 ,74LS373, 74LS138 基本可实现。244可以组成4进4出, 373可以用于锁存,再用LS138解码就可以了。
硬件上最简单的解决方案是:使用一片altera MAXII EPM240 CPLD。 100脚芯片,接单片机 19个脚,单片机还有 13个脚,然后CPLD再扩展出 51个脚,绰绰有余。
我用595 和597
卧槽8255神马的应该可以,非要这么写程序吗,我从来就是165 164的,端口少,扩展简单
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或& &  刚好勉勉强强看懂一行程序
  继续学习中,先把开发板自带一个例子做了些精简,以免看得吓人。。。。      就是这个,让PORTD上接的4个分别点亮。   开始研究代码   int main(void)   {   Init_All_Periph();   。。.。。.   看到这一行,开始跟踪,于是又看到了下面的内容   void Init_All_Periph(void)   {   R_Configuration();   。。.。。.   继续跟踪   void RCC_Configuration(void)   {   Systnit();   。。.。。.   这行代码在system_stm32f10x.c中找到了。   void SystemInit (void)   {   /* Reset the RCC ck configuration to the default reset state(for debug purpose) */   /* Set HSION bit */   RCC-》CR |= (uint32_t)0x;   /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */   #ifndef STM32F10X_CL   RCC-》CFGR &= (uint32_t)0xF8FF0000;   #else   RCC-》CFGR &= (uint32_t)0xF0FF0000;   #endif /* STM32F10X_CL */   /* Reset HSEON, CSSON and ON bits */   RCC-》CR &= (uint32_t)0xFEF6FFFF;   /* Reset HSEBYP bit */   RCC-》CR &= (uint32_t)0xFFFBFFFF;   /* Reset PLL, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */   RCC-》CFGR &= (uint32_t)0xFF80FFFF;   #ifndef STM32F10X_CL   /* Dble all interrupts and clear pending bits */   RCC-》CIR = 0x009F0000;   #else   /* Reset PLL2ON and PLL3ON bits */   RCC-》CR &= (uint32_t)0xEBFFFFFF;   /* Disable all interrupts and clear pending bits */   RCC-》CIR = 0x00FF0000;   /* Reset CFGR2 register */   RCC-》CFGR2 = 0x;   #endif /* STM32F10X_CL */   /* Configure the System clock , HCLK, PCLK2 and PCLK1 prescalers */   /* Configure the Flash Latency cycles and enable prefetch buffer */   SetSysClock();   }   这一长串的又是什么,如何来用呢?看来,偷懒是不成的了,只能回过头去研究STM32的时钟构成了。   相当的复杂。
& &  系统的时钟可以有3个来源:内部时钟HSI,外部时钟HSE,或者PLL(模块)的输出。它们由RCC_CFGR寄存器中的SW来选择。   SW(1:0):系统时钟切换   由软件置&1&或清&0&来选择系统时钟源。 在从停止或待机模式中返回时或直接或间接作为系统时钟的HSE出现故障时,由硬件强制选择HSI作为系统时钟(如果时钟安全系统已经启动)   00:HSI作为系统时钟;   01:HSE作为系统时钟;   10:PLL输出作为系统时钟;   11:不可用。   ////////////////////////////////////////////////////////////////////   PLL的输出直接送到USB模块,经过适当的后得到48M的供USB模块使用。   系统时钟的一路被直接送到I2S模块;另一路经过AHB分频后送出,送往各个系统,其中直接送往,SC,AHB总线;8分频后作为系统定时器时钟;经过APB1分频分别控制PLK1、定时器TIM2~TIM7;经过APB2分频分别控制PLK2、定时器TIM1~TIM8、再经分频控制ADC;   由此可知,STM32F10x芯片的时钟比之于51、AVR、P等8位机要复杂复多,因此,我们立足于对着芯片手册来解读程序,力求知道这些程序代码如何使用,为何这么样使用,如果自己要改,可以修改哪些部分,以便自己使用时可以得心应手。   单步执行,看一看哪些代码被执行了。   /* Reset the RCC clock configuration to the default reset state(for debug purpose) */   /* Set HSION bit */   RCC-》CR |= (uint32_t)0x;      这是RCC_CR寄存器,由图可见,HSION是其bit 0位。   HSION:内部高速时钟使能   由软件置&1&或清零。   当从待机和停止模式返回或用作系统时钟的外部4-25M时钟发生故障时,该位由硬件置&1&来启动内部8MHz的RC。当内部8MHz时钟被直接或间接地用作或被选择将要作为系统时钟时,该位不能被清零。   0:内部8MHz时钟关闭;   1:内部8MHz时钟开启。   ///////////////////////////////////////////////////////////////////////   /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */   #ifndef STM32F10X_CL   RCC-》CFGR &= (uint32_t)0xF8FF0000;      这是RCC_CFGR寄存器   该行程序清零了MC0[2:0]这三位,和ADCPRE[1:0],ppre2[2:0],PPRE1[2:0],HPRE[3:0],SWS[1:0]和SW[1:0]这16位。   /*   MCO: 微控制器时钟输出,由软件置&1&或清零。   0xx:没有时钟输出;   100:系统时钟(SYSCLK)输出;   101:内部8MHz的RC振荡器时钟输出;   110:外部4-25MHz振荡器时钟输出;   111:PLL时钟2分频后输出。   */   /* Reset HSEON, CSSON and PLLON bits */   RCC-》CR &= (uint32_t)0xFEF6FFFF;   清零了PLLON,HSEBYP,HSERDY这3位。   /* Reset HSEBYP bit */   RCC-》CR &= (uint32_t)0xFFFBFFFF;   清零了HSEBYP位 ///???为什么不一次写??   HSEBYP:外部高速时钟旁路,在调试模式下由软件置&1&或清零来旁路外部晶体振荡器。只有在外部4-25MHz振荡器关闭的情况下,才能写入该位。   0:外部4-25MHz振荡器没有旁路;   1:外部4-25MHz外部晶体振荡器被旁路。   所以要先清HSEON位,再清该位。   /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */   RCC-》CFGR &= (uint32_t)0xFF80FFFF;   清零了:USBPRE,PLLMUL,PLLXTPR,PLLSRC共7位   /* Disable all interrupts and clear pending bits */   RCC-》CIR = 0x009F0000;   ////这个暂不解读   SetSysClock();  跟踪进入该函数,可见一连串的条件编译:
&   单步运行,执行的是:   #elif defined SYSCLK_FREQ_72MHz   SetSysClockTo72();   为何执行该行呢,找到SYSCLK_PREQ_**的相关定义,如下图所示。      这样就得到了我们所要的一个结论:如果要更改系统工作频率,只需要在这里更改就可以了。   可以继续跟踪进入这个函数来观察如何将工作频率设定为72MHz的。   static void SetSysClockTo72(void)   {   __IO uint32_t StartUpCounter = 0, HSEStatus = 0;   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/   /* Enable HSE */   RCC-》CR |= ((uint32_t)RCC_CR_HSEON);   //开启HSE   /* Wait till HSE is ready and if Time out is reached exit */   do   {   HSEStatus = RCC-》CR & RCC_CR_HSERDY;   StartUpCounter++;   } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));   //等待HSE确实可用,这有个标志,即RCC_CR寄存器中的HSERDY位(bit 17),这个等待不会无限长,有个超时策略,即每循环一次计数器加1,如果计数的次数超过HSEStartUp_TimeOut,就退出循环,而这个HSEStartUp_TimeOut在stm32f10x.h中定义,   #define HSEStartUp_TimeOut ((uint16_t)0x0500) /*!《 Time out for HSE start up */   ///////////////////////////////////////////////////////////////////////////////////////////////   if ((RCC-》CR & RCC_CR_HSERDY) != RESET)   {   HSEStatus = (uint32_t)0x01;   }   else   {   HSEStatus = (uint32_t)0x00;   }   ///再次判断HSERDY标志位,并据此给HSEStatus变量赋值。   if (HSEStatus == (uint32_t)0x01)   {   /* Enable Prefetch Buffer */   FLASH-》ACR |= FLASH_ACR_PRFTBE;   /* Flash 2 wait state */   FLASH-》ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);   FLASH-》ACR |= (uint32_t)FLASH_ACR_LATENCY_2;   /* HCLK = SYSCLK */   RCC-》CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;   //找到定义: #define RCC_CFGR_HPRE_DIV1 ((uint32_t)0x) /*!《 SYSCLK not divided */   /* PCLK2 = HCLK */   RCC-》CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;   //找到定义:#define RCC_CFGR_PPRE2_DIV1 ((uint32_t)0x) /*!《 HCLK not divided */   /* PCLK1 = HCLK */   RCC-》CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;   //找到定义:#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x) /*!《 HCLK divided by 2 */   #ifdef STM32F10X_CL   &&   #else   /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */   RCC-》CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |   RCC_CFGR_PLLMULL));   RCC-》CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);   #endif /* STM32F10X_CL */   //以上是设定PLL的系数为9,也就是说,这个72M是在外部为8M时得到的。   /* Enable PLL */   RCC-》CR |= RCC_CR_PLLON;   /* Wait till PLL is ready */   while((RCC-》CR & RCC_CR_PLLRDY) == 0)   {   }   /* Select PLL as system clock source */   RCC-》CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));   RCC-》CFGR |= (uint32_t)RCC_CFGR_SW_PLL;   /* Wait till PLL is used as system clock source */   while ((RCC-》CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)   {   }   }   else   { /* If HSE fails to start-up, the application will have wrong clock   configuration. User
add here some code to deal with this error */   /* Go to infinite loop */   while (1)   {   }   }   }
  至此,我们可以归纳几条:   (1) 时钟源有3个   (2) 开机时默认是HSI起作用,可以配置为所要求的任意一个时钟   (3) 配置时必须按一定的顺序来打开或都关闭一些位,并且各时钟起作用有一定的时间,因此要利用芯片内部的标志位来判断是否可以执行下一步。   (4) 如果外部时钟、PLL输出失效,系统可以自动回复到HSI(开启时钟安全系统)   (5) HSI的频率准确度可以达到+/- 1%,如果有必要时,还可以用程序来调整这个频率,可调的范围大致在200KHz左右。   最后让我们来感受一下劳动的果实吧--试着改改频率看有何反应。   为查看更改后的效果,先记录更改前的数据。将调试切换到仿真,在第一条:   Delay(0xAFFFF);   指令执行前后,分别记录下Status和Sec   Status:   Sec:0..   将振荡频率更改为36MHz,即   。。.   #define SYSCLK_FREQ_36MHz
//去掉该行的注释   /* #define SYSCLK_FREQ_48MHz
*/   /* #define SYSCLK_FREQ_56MHz
*/   /*#define SYSCLK_FREQ_72MHz */ //将该行加上注释   再次运行,结果如下:   Status:   Sec:0..   基本上是延时时间长了一倍。改成硬件仿真,将代码写入板子,可以看到LED闪烁的频率明显变慢了。
  前面的例子研究了时钟,接下来就来了解一下引脚的情况   Main.c中,有关I/O口的配置代码如下:   void GPIO_Configuration(void)   {   GPIO_InitTypeDef GPIO_InitS   /* Configure IO connected to LD1, LD2, LD3 and LD4 leds *********************/   GPIO_InitStructure.GPIO_ = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   GPIO_Init(GPIOD, &GPIO_InitStructure);   这几行代码是将GPIOD的第8,9,10和11引脚配置成输出,并且还可以设定输出引脚的速度(驱动能力?),这里设定为 50MHz,这应该是常用的,还有可以设置为2MHz的。那么如何将引脚设置成输入呢?查看原理图,GPIOD.0~GPIO.4是接一个摇杆的5个按钮的,因此,下面尝试着将它们设置成为输入端。   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   GPIO_Init(GPIOD, &GPIO_InitStructure);   第1行和第3行完全是照抄,第2行那个GPIO_Mode_IN_FLOATING是在stm32f10x_gpio.h中找到的。      当然是因为这里还有GPIO_Mode_Out_PP,所以猜测应该是它了。至于还有其他那么多的符号就不管了。   定义完成,编译完全通过,那就接下来准备完成下面的代码了。   int main(void)   {   Init_All_Periph();   while(1)   { if( GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_0)) //1   { GPIO_ResetBits(GPIOD, GPIO_Pin_8);   }   else   { /* Turn on LD1 */   GPIO_SetBits(GPIOD, GPIO_Pin_8);   /* Insert delay */   }   。。.。。.   标号为1的行显然其作用是判断GPIOD.0引脚是0还是1。这个函数是在stm32f10x_gpio.c中找到的。   uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)   {   uint8_t bitstatus = 0x00;   /* Check the parameters */   assert_param(IS_GPIO_ALL_PERIPH(GPIOx));   assert_param(IS_GET_GPIO_PIN(GPIO_Pin));   if ((GPIOx-》IDR & GPIO_Pin) != (uint32_t)Bit_RESET)   {   bitstatus = (uint8_t)Bit_SET;   }   else   {   bitstatus = (uint8_t)Bit_RESET;   }      }   虽然程序还有很多符号看不懂(没有去查),但凭感觉它应该是对某一个引脚的状态进行判断,因为这个函数的类型是uint8_t,估计stm32没有bit型函数(需要验证),所以就用了uint8_t型了),如果是读的端口的值,应该用uint16_t型。这一点在下面也可以得到部分的验证:   uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)   uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)   这些函数是读引脚及输出寄存器的数据的。
 再次编译,也是顺利通过,依法炮制,将其他三个引脚输入控制LED的代码也写上,为保险起见,先用软件仿真,免得反复擦写FLASH(顺便说一句,目前还没有搞定将代码写入RAM及从RAM中执行)      进入仿真后打开外围部件接口,单步执行,果然如同设想那样运作了,单击Pins 0后面的勾,再次运行,果然PIN8后面的勾没了。做到这里,就感觉到用keil的好处了,这块熟啊,几乎没有花时间在上面,一用就成了。
本网站试开通微、小企业商家广告业务;维修点推荐项目。收费实惠有效果!欢迎在QQ或邮箱联系!
试试再找找您想看的资料
资料搜索:
查看相关资料 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
copyright & &广电电器(中国梧州) -all right reserved& 若您有什么意见或建议请mail: & &
地址: 电话:(86)774-2826670&用心创造滤镜
扫码下载App
汇聚2000万达人的兴趣社区下载即送20张免费照片冲印
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
下面用一个闪烁灯的例子来说明51单片机单个i/o口的用法:
/*****************************************************************************
晶振:11.0593MHz
LED接P1.0引脚
实验结果:LED每隔0.5s闪烁一次
*******************************************************************************/
#include&reg51.h&&&& //包含头文件
#define LED P1.0&&&& //定义LED为P1.0口
void delay(unsigned int i)&& //延时1ms函数
&& for(;i&0;i--)
&&&&& for(int j=0;j&110;j++);
void main()&&&&&&&&&&&&&& //主函数
&& while(1)
&&&&&&&LED=1;&&&&&&&&&&&&&//熄灭LED
&&&&&&&delay(500);&&&&&&&&//延时0.5s
&&&&&& LED=0;&&&&&&&&&&& //点亮LED
&&&&&&&delay(500);
下面再用一个流水灯例子说明51单片机整体I/O的用法:
/*****************************************************************************
晶振:11.0593MHz
8个LED1~LED8分别接接P1.0~P1.7引脚
实验结果:从LED1至LED8逐个点亮,呈现流水灯效果
*******************************************************************************/
#include&reg51.h&
void delay(unsigned int i)&& //延时1ms函数
&& for(;i&0;i--)
&&&&& for(int j=0;j&110;j++);
void main()
&& while(1)
&&&&& P1=0xFF;&&&&&&//就是二进制中的,全部熄灭
&&&&&&delay(100);& //延时0.1s
&&&& &P1=0xFE;&&&& //就是二进制中的,点亮LED1
&&&&& delay(100);& //延时0.1s
&&&&& P1=0xFD;&&&&&&//就是二进制中的,点亮LED2
&&&&&&delay(100);& //延时0.1s
&&&&& P1=0xFB;&&&&&&//就是二进制中的,点亮LED3
&&&&&&delay(100);& //延时0.1s
&&&&& P1=0xF7;&&&&&&//就是二进制中的,点亮LED4
&&&&&&delay(100);& //延时0.1s
&&&&& P1=0xEF;&&&&&&//就是二进制中的,点亮LED5
&&&&&delay(100);& //延时0.1s
&&&&& P1=0xDF;&&&&&&//就是二进制中的,点亮LED6
&&&&&delay(100);& //延时0.1s
&&&&& P1=0xBF;&&&&&&//就是二进制中的,点亮LED7
&&&&&delay(100);& //延时0.1s
&&&&& P1=0x7F;&&&&&&//就是二进制中的,点亮LED8
&&&&&delay(100);& //延时0.1s
阅读(1081)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'51单片机IO口操作',
blogAbstract:'
&&&&&&& 51单片机中有四个i/o口,分别是P1,P2,P3和P4,每个引脚不止一种功能(如P3.2既是i/o口又是外部中断INT0引脚)。
下面用一个闪烁灯的例子来说明51单片机单个i/o口的用法:
/*****************************************************************************
晶振:11.0593MHz
LED接P1.0引脚
实验结果:LED每隔0.5s闪烁一次
*******************************************************************************/
#include&reg51.h&&&& //包含头文件
#define LED P1.0&&&& //定义LED为P1.0口
void delay(unsigned int i)&& //延时1ms函数',
blogTag:'51单片机,io口,51单片机学习笔记,学习笔记',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:9,
publishTime:7,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}单片机输入IO口扩展_百度知道
单片机输入IO口扩展
单片机的输入IO口扩展可以通过以下方法来实现:1、通过并行扩展芯片,比如8255 ,8155等。2、通过锁存器或缓冲器来扩展,比如74LS273,74LS373,74LS244,74LS245等等3、通过串口-并口来扩展,比如74HC595,74HC164等等。4、通过译码器来扩展,比如74HC138,74HC154等等。
其他类似问题
为您推荐:
提问者采纳
1.同意楼上的说法,最好是换一个多I/O口的单片机,现在单片机也不贵,就换一个80个或100个I/O口的单片机,比扩展8255之类的简单多了,现在扩展都没有用8255的,都停产了,有的地方买都买不到。2.还有个方案就是再用一片单片机扩展,两个单片机用串口或IIC之类的协议进行通讯,一个专门管输入,另一个专门管输出,不过肯定没有一个单片机方便。
有没有什么单片机可以推荐的,,并且价格差不多的。。
AVR的单片机ATmega1280,淘宝上卖还不到50块钱,有86个I/O口
现在我做的这个东西是需要严格的控制价格的。。50块钱的话,就会比较贵的了。
那就用两个40脚的单片机吧,一个管输入,一个管输出,也不麻烦
其他3条回答
直接用一块 & 32个IO口 就不需要扩展,硬件又简单,40 脚的单片机 可以有 36 个 IO 口。
开来你需要换单片机了,换引脚多的单片机不就可以了么?为什么非要加扩展芯片呢?加扩展芯片成本估计还要比换个单片机还要贵 。
直接用一块 & 32个IO口 就不需要扩展,硬件又简单,40 脚的单片机 可以有 36 个 IO 口。 赞同1.同意楼上的说法,最好是换一个多I/O口的单片机,现在单片机也不贵,就换一个80个或100个I/O口的单片机,比扩展8255之类的简单多了,现在扩展都没有用8255的,都停产了,有的地方买都买不到。2.还有个方案就是再用一片单片机扩展,两个单片机用串口或IIC之类的协议进行通讯,一个专门管输入,另一个专门管输出,不过肯定没有一个单片机方便。
开来你需要换单片机了,换引脚多的单片机不就可以了么?为什么非要加扩展芯片呢?加扩展芯片成本估计还要比换个单片机还要贵
有没有什么单片机可以推荐下呢。
您可能关注的推广回答者:
单片机的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁关于51单片机IO口接按键的疑问我刚开始学单片机,目前学到按键部分我看到单片机的IO脚是直通按键的,而按键的另一端是直接接地的,没有其他东西。假设给IO口赋高电平,也就是5V,那么按键按下的时候,不就是相当于与地短路了吗?单片机不怕烧吗?可能短时间没事,如果长时间按下呢?--参考方法--没事 io口输出电流很小 都没有什么驱动能力
把正5v接io口当高电平也没事
只有大电流大电压通过单片机才会烧
--参考方法--如果单片机IO没有上拉的话,最好外接上拉电阻否则,在没有按键的时候IO输入状态不确定在输出状态下,单片机内部会有限流的。
--参考方法--
51单片机端口具有弱上拉功能,作为输入前,先要输出1。如果按键没按下,读到的是高电平;按下后接地,读到的是低电平,表示有按键。由于是弱上拉,即使持续将该端口对地短路,输出电流也小于1毫安(一般只有几百微安),不会烧端口。但,端口直接接5伏电源不可行,因为如果输出0,5伏倒灌进去,电流很大,会烧管脚的。
随机推荐程序问答结果
如对文章有任何疑问请提交到,或者您对内容不满意,请您反馈给我们发贴求解。
,机器学习分类整理更新日期:: 19:04:19
如需转载,请注明文章出处和来源网址:
本文WWW.DOC100.NET DOC100.NET版权所有。

我要回帖

更多关于 单片机io口扩展 的文章

 

随机推荐