<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>空雪小屋 &#187; 单片机</title>
	<atom:link href="http://blog.sorayuki.net/?cat=18&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.sorayuki.net</link>
	<description>现在域名是 blog.sorayuki.net ~</description>
	<lastBuildDate>Tue, 29 Nov 2022 08:27:41 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.0</generator>
	<item>
		<title>EEPROM的操作与DS1302数字时钟</title>
		<link>http://blog.sorayuki.net/?p=287</link>
		<comments>http://blog.sorayuki.net/?p=287#comments</comments>
		<pubDate>Sat, 18 May 2013 09:22:10 +0000</pubDate>
		<dc:creator><![CDATA[空雪梦见]]></dc:creator>
				<category><![CDATA[单片机]]></category>

		<guid isPermaLink="false">http://blog.sorayuki.net/?p=287</guid>
		<description><![CDATA[因为昨天已经开始看EEPROM的文档了，今天就想按照文档中的试验一下，存数据进去掉电不会消失。至于DS1302 &#8230; <a href="http://blog.sorayuki.net/?p=287" class="more-link">继续阅读<span class="screen-reader-text">EEPROM的操作与DS1302数字时钟</span> <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>因为昨天已经开始看EEPROM的文档了，今天就想按照文档中的试验一下，存数据进去掉电不会消失。至于DS1302芯片，是因为中午饭后搞定了EEPROM，所以就决定再做一个实验。总体来说不难，关键是有几个地方掉坑了……</p>
<p><span id="more-287"></span></p>
<p><strong>注：因为本无产阶级买不起示波器，所以这里的图是凭借实验加上想象来画的……</strong></p>
<p>EEPROM用的芯片是AT24C02，有256字节的存储空间。根据文档，它有8个腿，A0 A1 A2是用于识别设备的，这样多个这样的芯片可以共享一个总线IO。因为这板子上就一个这种芯片，就直接把A0 A1 A2全部接地了（都是低电平），于是这块芯片在板子上的设备ID就是0。Vcc连电源，SDA按照板子的手册，是连在P33上的，SCL是连在P32上的。通过P33和P32来和它通信。SDA跑信号的，SCL用于同步的。</p>
<p>EEPROM的SCL是用来同步的，我本来以为它每变化一次电平就可以通过SDA发送或接收一个信号，但是结果当然是失败的……它不是这么用的。仔细看说明以后得知，是SCL变为高电平的期间，SDA用于发送或者接受数据。例如要发送1，就把SDA弄成高电平，然后往SCL输出一个脉冲（先变高电平然后变回来）。发送0方法相同，把SDA弄成低电平，然后往SCL输出一个脉冲。接收的话，先把SDA置为高电平，然后往SCL送一个脉冲信号，在此过程中检查SDA是不是变成低电平了，<strong>检查过程是在脉冲之中，又要考虑它的反应速度所以在脉冲中偏后的位置似乎会比较好</strong>。如果变成低电平，那么说明收到的是0；否则说明收到的是1。这一系列芯片能接受的速度最低的似乎只有100KHz，我就按照这个100KHz来搞，慢是慢一点毕竟是实验。</p>
<p>它的使用手册上定义，SCL高电平的时候SDA的信号要求是稳定的，信号改变只能在低电平的时间内改变。于是要留下足够多的时间给AT24C02去反应，因为它速度只有100KHz。</p>
<p>我只用到了它的指定地址单个字节读取和指定地址单个字节写入功能。对于往指定地址写一个字节，过程是：（A代表单片机主动（输出），P代表单片机被动（输入））</p>
<p>START(A) –&gt; 设备编号(A) –&gt; ACK(P) –&gt; 地址(A) –&gt; ACK(P) –&gt; 数据(A) –&gt; ACK –&gt; STOP</p>
<p>其中START的定义是，保持SCL高电平的同时，SDA从高电平变到低电平。STOP的定义是，保持SCL高电平的同时，SDA从低电平变到高电平。ACK的定义是，SDA变为低电平（就是对方发了一个0过来）。这里面有个应该说常识性问题我不知道的呢还是什么的，因为我之前不知道引脚用作输入的话要预先设置为高电平……（汗）</p>
<p>于是先定义两个函数，用于输出1和输出0。然后用这两个函数组成发送/接收一个字节的功能，因为上述设备编号、地址、数据都是8位，正好一个字节。</p>
<p>测试的时候，能收到ACK大致就可以认为大功告成了……</p>
<p>然后是读取，比写入更复杂不少。</p>
<p>START(A) –&gt; 设备编号(A) –&gt; ACK(P) –&gt; 地址(A) –&gt; ACK(P) –&gt; START(A) –&gt; 设备编号(A) –&gt; ACK(P) –&gt; DATA(P) –&gt; STOP</p>
<p>其中前半部分和写入类似，不过到要发数据的时候变成发一个START过去，以及最后拿完数据不需要ACK(A)。</p>
<p>关于里面那个设备编号，它的前4位固定是1010，然后是A0 A1 A2引脚决定的编号，我这边是三个0。最后一位代表请求类型，是要读取还是写入。前者用1后者用0。比如这个情况我要写入，那么这个“设备编号”就是10100000。至于地址，就是0~255一共256个字节，AT24C02的容量也就这么256字节而已。数据就是一个字节的数据。<strong>注意的是发送过程中，所有字节都是“最高位优先（MSF）”的</strong>。比如要发送0x30，那么实际发送的比特流是 00110000。</p>
<p>实验是不难。关键是我之前掉坑了……就是端口用于输入的话要先设置为高电平的坑囧。</p>
<p><a href="http://blog.sorayuki.net/wp-content/uploads/2013/05/eeprom_signal.jpg"><img class="alignnone size-full wp-image-295" title="eeprom_signal" src="http://blog.sorayuki.net/wp-content/uploads/2013/05/eeprom_signal.jpg" alt="" width="387" height="644" /></a></p>
<p>&nbsp;</p>
<p>因为这个实验中午饭后就成功了，于是下午就决定研究一下DS1302数字时钟芯片。这个芯片的通信甚至比上面那个更简单，但是也是因为坑……啊啊一大堆坑（死目</p>
<p>它的通信和AT24C02有点不太一样，AT24C02不是上来直接给它发送数据就成了吗？DS1302不行，要先把CE引脚设为高电平，才能给它发请求……</p>
<p>还有，关于通信的时候它也是一个引脚同步一个引脚信号，但是关于同步信号的处理有一点不同。虽然发送数据的时候确实也是在脉冲中发的，但是从它<strong>接收数据的时候，是在脉冲之后接收，而不是脉冲之中</strong>……而且官方文档中没发现它能以多块的频率工作，于是也不知道到底应该以什么样的速度发送才好，就胡乱设了一个delay（胡乱……）。另外和AT24C02不同，DS1302芯片对数据的处理是“最小位优先（LSF）”的。比如要发送0x30，实际发送的比特流是 00001100。每个请求是一个字节，每个数据也是一个字节，操纵它就是给CE高电平，发送一个字节的请求，然后根据请求是读或者是写，来发送或者接收一个字节，完了取消CE的高电平即可。</p>
<p><a href="http://blog.sorayuki.net/wp-content/uploads/2013/05/ds1302_signal.jpg"><img class="alignnone size-full wp-image-301" title="ds1302_signal" src="http://blog.sorayuki.net/wp-content/uploads/2013/05/ds1302_signal.jpg" alt="" width="387" height="396" /></a></p>
<p>这里面又遇到一个坑，就是发送请求完毕之后，如果是读取请求，这个时候不是应该接收数据吗？然后我刚才是不是有说过，从它接收数据是在低电平的时候？没错，问题就在这里……<strong>第一个要接收的比特在你发送完请求的最后一个比特之后，SCLK设为低电平之后，马上就开始返回了！而不是等到你给SCLK下一个脉冲。</strong>我一开始写的程序没考虑到这个，发完最后一个比特的请求数据、SCLK变回低电平之后，给了它一个脉冲才开始接收下一个数据，然后就是发现每两秒屏幕上的数字才会变一次，而且变得很诡异（因为少了最后一位！）。这坑搞了我好一阵子……另一个卡了半死的地方就是CE的高电平，没给它设高电平就开始操作得有来有去，怪不得它不鸟我 ._.</p>
<p>读取秒的时候，保持CE高电平，数据口和时钟口的信号：</p>
<p><a href="http://blog.sorayuki.net/wp-content/uploads/2013/05/ds1302_signal2.jpg"><img class="alignnone size-full wp-image-300" title="ds1302_signal2" src="http://blog.sorayuki.net/wp-content/uploads/2013/05/ds1302_signal2.jpg" alt="" width="584" height="207" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sorayuki.net/?feed=rss2&#038;p=287</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>上淘宝搞了一片51单片机来玩</title>
		<link>http://blog.sorayuki.net/?p=285</link>
		<comments>http://blog.sorayuki.net/?p=285#comments</comments>
		<pubDate>Wed, 15 May 2013 00:39:31 +0000</pubDate>
		<dc:creator><![CDATA[空雪梦见]]></dc:creator>
				<category><![CDATA[单片机]]></category>

		<guid isPermaLink="false">http://blog.sorayuki.net/?p=285</guid>
		<description><![CDATA[淘宝上山东芯腾电子的店买了一块55元（运费不含）的学习板来玩。因为本科的时候没报这个方向，但是想试试看搞板子是 &#8230; <a href="http://blog.sorayuki.net/?p=285" class="more-link">继续阅读<span class="screen-reader-text">上淘宝搞了一片51单片机来玩</span> <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>淘宝上山东芯腾电子的店买了一块55元（运费不含）的学习板来玩。因为本科的时候没报这个方向，但是想试试看搞板子是什么一种感觉，于是自己花钱去弄了来。外加从图书馆搞了两本书对着学。</p>
<p>电路是现成的，主要是怕自己焊又没人指导搞不起来，花太多时间。<span id="more-285"></span></p>
<p>51单片机开发初学感觉不是很难，它芯片有很多很多脚，然后其中8个脚对应p0输出端口，8个对应p1，以此。因为一个字节是8位嘛，然后它就按照这8位的具体内容，往脚上送电，1代表没电0代表有电（反过来的……），在汇编程序里也就</p>
<p>mov p0, #0</p>
<p>p0上如果连着led，那么8个led就全亮了。如果</p>
<p>mov p0, #0xf0</p>
<p>就是其中四个亮了。</p>
<p>就是这么简单的mov语句而已，电路上看网上说直接连led同时串联1k电阻即可，引脚的输出的电可以直接推动led，不用搞三极管啥的。</p>
<p>烧程序它有一个宏晶公司的烧录程序，通过串口烧程序。板子上也都弄好了什么串口转usb的部分，usb连了板子装了驱动电脑上就能识别出一个com口。要不然现在笔记本电脑都没有串口位置了（怀疑这年头台式机可能也没）</p>
<p>然后接下来就玩了稍微复杂一些的，64个led组成的方阵来显示汉字。方法虽然说不是很难不过中途掉坑里了花了一点时间。因为它64个点阵实际上才接16根腿，8根表示行8根表示列，然后我上网找了一下方法说是一次显示一行，显示出一行后延时一下，然后显示下一行。最后实现也是这样做，所说的“坑”是指显示一行跳到下一行之前，没有把显示的内容清空（全灭），这样效果很恶心……还有就是什么时候0是亮什么时候0是灭这个有点混淆。</p>
<p>暂时玩过的部分还有一个就是字幕滚动，在上面那个的基础上使用定时器中断，让显示的内容每次移动一点。技巧是把字转个90度，然后每次从最上方减少一行，最下方补充一行，这样整体就移动了一行。</p>
<p>没玩过这种cpu只执行我的代码、完全对裸机编程的。感觉比较新鲜</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sorayuki.net/?feed=rss2&#038;p=285</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
