<?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://ichaochao.com/category/%e5%81%87%e8%a3%85%e6%87%82%e6%8a%80%e6%9c%af/feed/" rel="self" type="application/rss+xml" />
	<link>http://ichaochao.com</link>
	<description></description>
	<lastBuildDate>Wed, 04 Jan 2012 06:58:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ACER AL2216W 液晶显示器维修手记</title>
		<link>http://ichaochao.com/2010/07/21/acer_al2216w/</link>
		<comments>http://ichaochao.com/2010/07/21/acer_al2216w/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 03:27:32 +0000</pubDate>
		<dc:creator>chaochao</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[非专业挨踢]]></category>

		<guid isPermaLink="false">http://ichaochao.com/?p=360</guid>
		<description><![CDATA[作为一个资深电子工程师，家里的电子设备如果坏了，首先想到的就是自己修。虽然我这个人比较懒，但是凭着对自己所学科目的兴趣，小到儿子的电动玩具，大到空调电视机，都尝试过自己维修。至于修复率么&#8230;&#8230;不谈也罢。
事实上，正因为自己维修成功的次数很少，所以要把这次难得的成功经验记录下来并炫耀一番  
这台ACER AL2216W显示器，是2006年底在新蛋网买的，价格是2600元。在15/17寸液晶显示器为主流的当时，22寸是相对高端的产品了，大部分品牌的价格在4000以上。ACER是当时最便宜的22‘LCD，这个价格到了我能接受的地步，也为了享受下载的高清电影，毫不犹豫的下单订购了。
这个显示器，我一直还是挺满意的，在这么大的尺寸前面，响应速度啥的指标都不再重要了。而且三年半了，贬值也不过差不多一半，在电子设备里算是保值的了。
从今年年初开始，显示器就会出现偶尔黑屏的现象，就是正常显示时，突然黑屏约1～2秒，然后就恢复了。问题不严重，也就没在意。
上个月开始，发现DVI接口没有显示了，只有VGA能用，凭着凑活一天是一天的理念，找了根VGA线接上继续用。
终于在本周，VGA也不显示了，不仅不显示，连电源指示灯都不亮了。在排除了电源线的因素后，我只能认定这个显示器是彻底坏掉了。
不管能不能修好，拆开看了再说。动手吧～

把液晶翻转过来，下面垫一块软布（这里是我儿子的尿布），有很明显的四颗螺丝，拆掉先。

只是拆掉这四颗螺丝，后壳是卸不下来的。找了一下，在底座内部还有两颗螺丝：

卸了之后，意外的发现这个底座仍然拆不下来。
我在这一步停了很久，找不到拆开的办法，在网上也找不到资料，可以说是一头雾水。
（拆开了修不好，不丢人。要是连拆都拆不开，我这个资深电子工程师脸往哪里搁啊！）
抱着死马当成活马医的想法，就算把外壳撬坏也非拆开不可。拿个一字起东敲敲，西撬撬。

重点研究了一下这个底座以及上面的盖子，觉得应该先想办法把盖子拿下来才行。然后终于被我发现了秘密～

图中红圈标出的就是卡口，由于底座盖子和整个后盖贴合的非常好，完全看不出有缝隙，所以也很难想到这里有卡口。
撬开后就好办了：

把四颗螺丝拆掉，就能看到底座盖住的一颗螺丝，也拆掉后，整个后盖就可以撬开了：

这个后盖是和前盖通过塑料卡扣卡住的，所以撬的时候要胆大心细，用力不能太猛也不能太软。有介绍说可以用信用卡来撬，不过我试了一下，卡的很紧，用信用卡根本不行，所以最后还是用一字起解决了问题。

伤痕累累～

接下来就简单了，先把接到按键板上的排线拔下来，也可以把按键板拿下来后拔线。
按键板也是通过左右两个卡扣固定的。

卸下面这块金属盖板，这块板有两个塑料卡扣卡住，需要撬一下卡扣才能取下来。
话说我非常讨厌塑料卡扣，每次撬时都得小心翼翼别撬断了。

拆中间的金属盖板，需要先把电源接口和视频接口上的螺钉全部卸掉，因为这些接口是固定在线路板上而不是盖板上的。

终于看到线路板的真相了。很简单，左边是电源板，右边是数字控制板。
由于是电源指示灯不亮，所以估计电源板的故障可能性较大。

电源板损坏比较好查，通常就是先看电容是否有鼓包，漏液等，这是最常见也是最直观的。
结果我看了半天，所有电容都是西装笔挺，没有任何怀孕和流血的迹象，而且其它元器件也没有任何烧毁和开裂的痕迹。
所有焊点均饱满光泽，完全不像有虚焊和脱焊的地方。
很失望～
接下来只能操起万用表了。测量各器件是否有短路或开路。
耐心的逐个测量，终于发现一个二极管两脚短路，焊下来后按型号查了资料，这是一个肖特基二极管。
型号为SB20200FCT。

在淘宝上搜了一下，没有相同型号，不过找到一个替代型号：MBRF20200CT。
8元/个，买了2个，连邮费一共26元。

换上后，按原样恢复，开机。
显示器重生了～！
后记：
1.其实液晶显示器的维修远比CRT显示器来的简单，即使做不到元件级维修，也可以做到板级维修。我这块电源板在淘宝上就有的买，45元/块，很便宜。
2.电源大概是损坏率比较高的部分，我7年前花了三千多买的15寸SAMSUNG液晶显示器，在去年也出现过没有显示的问题，经查是外置的电源适配器损坏，换了一个同型号的电源适配器就整好了。
]]></description>
			<content:encoded><![CDATA[<p>作为一个<span style="text-decoration: line-through;">资深</span>电子工程师，家里的电子设备如果坏了，首先想到的就是自己修。虽然我这个人比较懒，但是凭着对自己所学科目的兴趣，小到儿子的电动玩具，大到空调电视机，都尝试过自己维修。至于修复率么&#8230;&#8230;不谈也罢。</p>
<p>事实上，正因为自己维修成功的次数很少，所以要把这次难得的成功经验记录下来并炫耀一番 <img src='http://ichaochao.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>这台ACER AL2216W显示器，是2006年底在新蛋网买的，价格是2600元。在15/17寸液晶显示器为主流的当时，22寸是相对高端的产品了，大部分品牌的价格在4000以上。ACER是当时最便宜的22‘LCD，这个价格到了我能接受的地步，也为了享受下载的高清电影，毫不犹豫的下单订购了。</p>
<p>这个显示器，我一直还是挺满意的，在这么大的尺寸前面，响应速度啥的指标都不再重要了。而且三年半了，贬值也不过差不多一半，在电子设备里算是保值的了。</p>
<p>从今年年初开始，显示器就会出现偶尔黑屏的现象，就是正常显示时，突然黑屏约1～2秒，然后就恢复了。问题不严重，也就没在意。</p>
<p>上个月开始，发现DVI接口没有显示了，只有VGA能用，凭着凑活一天是一天的理念，找了根VGA线接上继续用。</p>
<p>终于在本周，VGA也不显示了，不仅不显示，连电源指示灯都不亮了。在排除了电源线的因素后，我只能认定这个显示器是彻底坏掉了。</p>
<p>不管能不能修好，拆开看了再说。动手吧～<br />
<span id="more-360"></span></p>
<p>把液晶翻转过来，下面垫一块软布（这里是我儿子的尿布），有很明显的四颗螺丝，拆掉先。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9698.jpg"><img class="alignnone size-full wp-image-362" title="AL2216W_1" src="http://ichaochao.com/wp-content/uploads/2010/07/9698.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>只是拆掉这四颗螺丝，后壳是卸不下来的。找了一下，在底座内部还有两颗螺丝：</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9697.jpg"><img class="alignnone size-full wp-image-364" title="AL2216W_2" src="http://ichaochao.com/wp-content/uploads/2010/07/9697.jpg" alt="ACER AL2216W" width="504" height="272" /></a></p>
<p>卸了之后，意外的发现这个底座仍然拆不下来。</p>
<p>我在这一步停了很久，找不到拆开的办法，在网上也找不到资料，可以说是一头雾水。<br />
（拆开了修不好，不丢人。要是连拆都拆不开，我这个<span style="text-decoration: line-through;">资深</span>电子工程师脸往哪里搁啊！）</p>
<p>抱着死马当成活马医的想法，就算把外壳撬坏也非拆开不可。拿个一字起东敲敲，西撬撬。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9691.jpg"><img class="alignnone size-full wp-image-366" title="AL2216W_3" src="http://ichaochao.com/wp-content/uploads/2010/07/9691.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>重点研究了一下这个底座以及上面的盖子，觉得应该先想办法把盖子拿下来才行。然后终于被我发现了秘密～</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9693.jpg"><img class="alignnone size-full wp-image-367" title="AL2216W_4" src="http://ichaochao.com/wp-content/uploads/2010/07/9693.jpg" alt="ACER AL2216W" width="504" height="408" /></a></p>
<p>图中红圈标出的就是卡口，由于底座盖子和整个后盖贴合的非常好，完全看不出有缝隙，所以也很难想到这里有卡口。</p>
<p>撬开后就好办了：</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9687.jpg"><img class="alignnone size-full wp-image-368" title="AL2216W_5" src="http://ichaochao.com/wp-content/uploads/2010/07/9687.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>把四颗螺丝拆掉，就能看到底座盖住的一颗螺丝，也拆掉后，整个后盖就可以撬开了：</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9692.jpg"><img class="alignnone size-full wp-image-369" title="AL2216W_6" src="http://ichaochao.com/wp-content/uploads/2010/07/9692.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>这个后盖是和前盖通过塑料卡扣卡住的，所以撬的时候要胆大心细，用力不能太猛也不能太软。有介绍说可以用信用卡来撬，不过我试了一下，卡的很紧，用信用卡根本不行，所以最后还是用一字起解决了问题。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9686.jpg"><img class="alignnone size-full wp-image-371" title="AL2216W_6" src="http://ichaochao.com/wp-content/uploads/2010/07/9686.jpg" alt="ACER AL2216W" width="504" height="211" /></a></p>
<p>伤痕累累～</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9680.jpg"><img class="alignnone size-full wp-image-372" title="AL2216W_8" src="http://ichaochao.com/wp-content/uploads/2010/07/9680.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>接下来就简单了，先把接到按键板上的排线拔下来，也可以把按键板拿下来后拔线。<br />
按键板也是通过左右两个卡扣固定的。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9679.jpg"><img class="alignnone size-full wp-image-373" title="AL2216W_9" src="http://ichaochao.com/wp-content/uploads/2010/07/9679.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>卸下面这块金属盖板，这块板有两个塑料卡扣卡住，需要撬一下卡扣才能取下来。</p>
<p>话说我非常讨厌塑料卡扣，每次撬时都得小心翼翼别撬断了。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9678.jpg"><img class="alignnone size-full wp-image-374" title="AL2216W_A" src="http://ichaochao.com/wp-content/uploads/2010/07/9678.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>拆中间的金属盖板，需要先把电源接口和视频接口上的螺钉全部卸掉，因为这些接口是固定在线路板上而不是盖板上的。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9676.jpg"><img class="alignnone size-full wp-image-375" title="AL2216W_B" src="http://ichaochao.com/wp-content/uploads/2010/07/9676.jpg" alt="ACER AL2216W" width="504" height="275" /></a></p>
<p>终于看到线路板的真相了。很简单，左边是电源板，右边是数字控制板。</p>
<p>由于是电源指示灯不亮，所以估计电源板的故障可能性较大。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9638.jpg"><img class="alignnone size-full wp-image-376" title="AL2216W_C" src="http://ichaochao.com/wp-content/uploads/2010/07/9638.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>电源板损坏比较好查，通常就是先看电容是否有鼓包，漏液等，这是最常见也是最直观的。<br />
结果我看了半天，所有电容都是西装笔挺，没有任何怀孕和流血的迹象，而且其它元器件也没有任何烧毁和开裂的痕迹。<br />
所有焊点均饱满光泽，完全不像有虚焊和脱焊的地方。</p>
<p>很失望～</p>
<p>接下来只能操起万用表了。测量各器件是否有短路或开路。<br />
耐心的逐个测量，终于发现一个二极管两脚短路，焊下来后按型号查了资料，这是一个肖特基二极管。<br />
型号为SB20200FCT。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9675.jpg"><img class="alignnone size-full wp-image-377" title="AL2216W_D" src="http://ichaochao.com/wp-content/uploads/2010/07/9675.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>在淘宝上搜了一下，没有相同型号，不过找到一个替代型号：MBRF20200CT。<br />
8元/个，买了2个，连邮费一共26元。</p>
<p><a href="http://ichaochao.com/wp-content/uploads/2010/07/9724.jpg"><img class="alignnone size-full wp-image-378" title="AL2216W_E" src="http://ichaochao.com/wp-content/uploads/2010/07/9724.jpg" alt="ACER AL2216W" width="504" height="379" /></a></p>
<p>换上后，按原样恢复，开机。</p>
<p>显示器重生了～！</p>
<p>后记：</p>
<p>1.其实液晶显示器的维修远比CRT显示器来的简单，即使做不到元件级维修，也可以做到板级维修。我这块电源板在淘宝上就有的买，45元/块，很便宜。</p>
<p>2.电源大概是损坏率比较高的部分，我7年前花了三千多买的15寸SAMSUNG液晶显示器，在去年也出现过没有显示的问题，经查是外置的电源适配器损坏，换了一个同型号的电源适配器就整好了。</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2010/07/21/acer_al2216w/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Cadence 学习笔记 &#8211; Allegro 篇 （三）</title>
		<link>http://ichaochao.com/2008/08/26/allegro3/</link>
		<comments>http://ichaochao.com/2008/08/26/allegro3/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 03:02:24 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[EDA]]></category>
		<category><![CDATA[PCB]]></category>

		<guid isPermaLink="false">http://ichaochao.com/2008/08/26/allegro3/</guid>
		<description><![CDATA[修改allegro变量文件，设置自定义快捷键。]]></description>
			<content:encoded><![CDATA[<p>修改变量文件，设置自定义快捷键。</p>
<p>Allegro可以通过修改env文件来设置快捷键，这对于从其它软件如protle或PADS迁移过来的用户来说，可以沿用以前的操作习惯，还是很有意义的。</p>
<p>先说一下Allegro的变量文件，一共有2个，一个是用户变量，一个是全局变量。</p>
<p>用户变量文件的位置，通过系统环境变量设置：系统属性-高级-环境变量，其中的Home值就是env所在目录。要注意的是，这里也有两个变量，一个是用户变量一个是系统变量，在用户变量里设置了Home之后就不需要在系统变量里再设置了，如果同时设置的话，会以用户变量的为准而忽略系统变量。比如我在用户变量里设置的Home目录为d:\temp，那么env文件就位于<font color="#ff8040">d:\temp\pcbenv</font>内。     <br />如果没有在系统属性里设置Home变量的路径，那么对于XP，会自动在C:\documents and settings\用户文件夹\pcbenv内产生env文件。对于2000，pcbenv目录位于C盘根目录下。</p>
<p>全局变量的位置，固定为软件安装目录内，比如我的就是:<font color="#ff8040">d:\cadence\spb_15.7\share\pcb\text</font>内。</p>
<p>通常建议修改用户变量env文件，而不要修改全局变量env文件，至于为什么，我也不知道:)</p>
<p>另外，这2个env文件，用户变量的优先级更高，就是说如果2个文件中的设置出现冲突，那么以用户变量env文件为准。</p>
<p>好了，搞清楚env文件的位置后，我们就可以来修改了。</p>
<p>用户变量env文件，是类似于下面的格式：</p>
<blockquote><p>source $TELENV </p>
<p>### User Preferences section      <br />### This section is computer generated.       <br />### Please do not modify to the end of the file.       <br />### Place your hand edits above this section.       <br />###       <br />set autosave_time = 15       <br />set autosave</p>
</blockquote>
<p>我们要设置的快捷键必须放置在### User Preferences section之前。</p>
<p>设置快捷键指令格式 ：</p>
<p>alias 快捷键 执行的命令   <br />例:alias Del delete</p>
<p>我的部分快捷键：</p>
<blockquote><p>alias Pgup zoom in     <br />alias Pgdown zoom out      <br />alias End redisplay      <br />alias Insert add connect      <br />alias Home zoom fit      <br />alias Del delete      <br />funckey &#8216; &#8216; iangle 90</p>
</blockquote>
<p>扩展技巧：</p>
<p>关于快捷键可替代的命令，并不仅限于一级菜单中原已有快捷键的命令，对于有多级菜单的命令，比如Display-Show rats-Net(点亮单个网络)，我们也可以用快捷键代替：alias F9 rats net。这个命令&quot;rats net&quot;会在你执行后出现在右下角cmd:的后面。这样可快捷的命令就随你设置了。</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/08/26/allegro3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>在MATLAB中仿真FFT</title>
		<link>http://ichaochao.com/2008/07/28/fft_in_matlab/</link>
		<comments>http://ichaochao.com/2008/07/28/fft_in_matlab/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 08:51:22 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[matlab]]></category>

		<guid isPermaLink="false">http://ichaochao.com/2008/07/28/fft_in_matlab/</guid>
		<description><![CDATA[一个在MATLAB中仿真FFT的程序，同时还附有随机噪声的FFT，有很直观的图形描述。]]></description>
			<content:encoded><![CDATA[<p>一个简单的仿真FFT程序，在MATLAB 6.5中测试通过。</p>
<blockquote><p>fs=1000;     <span style="color: #008000;">%采样率为1000<br />
</span>t=0:1/fs:1;  <span style="color: #008000;">%时长1s<br />
</span>f1=50;         <span style="color: #008000;">%信号1频率50Hz</span><br />
f2=200;       <span style="color: #008000;">%信号2频率200Hz</span><br />
x=sin(2*pi*f1*t)+sin(2*pi*f2*t);  <span style="color: #008000;">%生成含有2个频率的正弦波</span><br />
subplot(211)<br />
plot(x);<br />
title(&#8216;f1(50Hz)&amp;f2(200Hz)的正弦信号&#8217;)<br />
xlabel(&#8216;序列(n)&#8217;)<br />
grid on</p>
<p>number=512;    <span style="color: #008000;">% fft长度 </span><br />
y=fft(x,number);  <span style="color: #008000;">%求x的fft</span><br />
n=0:length(y)-1;<br />
f=fs*n/length(y);<br />
subplot(212)<br />
plot(f,abs(y));  <span style="color: #008000;">%如果不求abs，虚部将被省略</span><br />
title(&#8216;f1&amp;f2的正弦信号的FFT(512点)&#8217;)<br />
xlabel(&#8216;频率Hz&#8217;)<br />
grid on</p></blockquote>
<p><span id="more-178"></span></p>
<p>图形如下：</p>
<p><a class="highslide-image" onclick="return hs.expand(this);" href="http://ichaochao.com/wp-content/uploads/2008/07/fft.jpg"><img title="Click to enlarge" src="http://ichaochao.com/wp-content/uploads/2008/07/fft_s.jpg" alt="image" /></a></p>
<p>加上随机噪声：</p>
<blockquote><p>x=x+randn(1,length(x));<br />
subplot(211)<br />
plot(x);<br />
title(&#8216;原f1&amp;f2的正弦信号(含随机噪声)&#8217;)<br />
xlabel(&#8216;序列(n)&#8217;)<br />
grid on</p>
<p>y=fft(x,number);<br />
n=0:length(y)-1;<br />
f=fs*n/length(y);<br />
subplot(212)<br />
plot(f,abs(y));<br />
title(&#8216;原f1&amp;f2的正弦信号(含随机噪声)的FFT(512点)&#8217;)<br />
xlabel(&#8216;频率Hz&#8217;)<br />
grid on</p></blockquote>
<p>图形如下：</p>
<p><span style="background-color: #f1f1f1;"> </span> <a class="highslide-image" onclick="return hs.expand(this);" href="http://ichaochao.com/wp-content/uploads/2008/07/fft_n.jpg"><img title="Click to enlarge" src="http://ichaochao.com/wp-content/uploads/2008/07/fft_n_s.jpg" alt="image" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/28/fft_in_matlab/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MATLAB 之 SAVE命令</title>
		<link>http://ichaochao.com/2008/07/16/matlab_save/</link>
		<comments>http://ichaochao.com/2008/07/16/matlab_save/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 07:59:43 +0000</pubDate>
		<dc:creator>chaochao</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[matlab]]></category>

		<guid isPermaLink="false">http://ichaochao.com/2008/07/16/matlab_save/</guid>
		<description><![CDATA[学习条件很差，手上没有一本MATLAB的书，安装的D版MATLAB又文档不全，遇到问题只能用help命令来查找。
今天翻译了SAVE命令。
SAVE命令可以将工作区的变量保存到磁盘。

SAVE FILENAME&#160; &#8211; 将工作区的所有变量全部保存到名为FILENAME.mat的二进制&#34;MAT&#34;文件中。数据可以用LOAD命令载入。如果FILENAME没有扩展名，会被默认设定为.mat
仅仅输入SAVE命令，将会创建一个名为&#8217;matlab.mat&#8217;的二进制&#34;MAT&#34;文件。如果&#8217;matlab.mat&#8217;文件不可写将会出错。
SAVE FILENAME X &#8211; 仅保存X。
SAVE FILENAME X Y Z&#160; -&#160; 保存X,Y和Z。可以使用通配符&#8217;*'来保存匹配的变量。
ASCII选项：     SAVE &#8230;&#160; -ASCII&#160; -&#160; 无论文件使用什么扩展名，都使用8位ASCII来代替二进制     SAVE &#8230;&#160; -ASCII -DOUBLE&#160; -&#160; 生成16位ASCII的格式     SAVE &#8230;&#160; -ASCII -TABS&#160; -&#160; 使用制表符来定界     SAVE &#8230;&#160; -ASCII -DOUBLE -TABS&#160; -&#160; 16位ASCII的格式 制表符定界
MAT选项： <a href="http://ichaochao.com/2008/07/16/matlab_save/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>学习条件很差，手上没有一本MATLAB的书，安装的D版MATLAB又文档不全，遇到问题只能用help命令来查找。</p>
<p>今天翻译了SAVE命令。</p>
<p>SAVE命令可以将工作区的变量保存到磁盘。</p>
<p><span id="more-173"></span></p>
<p><strong>SAVE FILENAME</strong>&#160; &#8211; 将工作区的所有变量全部保存到名为FILENAME.mat的二进制&quot;MAT&quot;文件中。数据可以用LOAD命令载入。如果FILENAME没有扩展名，会被默认设定为.mat</p>
<p>仅仅输入SAVE命令，将会创建一个名为&#8217;matlab.mat&#8217;的二进制&quot;MAT&quot;文件。如果&#8217;matlab.mat&#8217;文件不可写将会出错。</p>
<p><strong>SAVE FILENAME X &#8211; </strong>仅保存X。</p>
<p><strong>SAVE FILENAME X Y Z</strong>&#160; -&#160; 保存X,Y和Z。可以使用通配符&#8217;*'来保存匹配的变量。</p>
<p><strong><u>ASCII选项：</u></strong>     <br /><strong>SAVE &#8230;&#160; -ASCII</strong>&#160; -&#160; 无论文件使用什么扩展名，都使用8位ASCII来代替二进制     <br /><strong>SAVE &#8230;&#160; -ASCII -DOUBLE</strong>&#160; -&#160; 生成16位ASCII的格式     <br /><strong>SAVE &#8230;&#160; -ASCII -TABS</strong>&#160; -&#160; 使用制表符来定界     <br /><strong>SAVE &#8230;&#160; -ASCII -DOUBLE -TABS</strong>&#160; -&#160; 16位ASCII的格式 制表符定界</p>
<p><strong><u>MAT选项：</u></strong>     <br /><strong>SAVE &#8230;&#160; -MAT</strong>&#160; -&#160; 无论文件使用什么扩展名，都保存为MAT格式。     <br /><strong>SAVE &#8230;&#160; -V4</strong>&#160; -&#160; 保存为MATLAB 4可以调用的MAT文件。     <br /><strong>SAVE &#8230;&#160; -APPEND</strong>&#160; -&#160; 将变量追加到一个已存在的文件中（仅限MAT文件）。</p>
<p>当使用-V4选项时，和MATLAB4不适配的变量将不会保存到MAT文件中。比如ND arrays, structs, cells等等，将不能存为MATLAB 4的MAT文件。    <br />同样的，名称超过19个字符的变量也无法保存到MATLAB4 的MAT文件中。</p>
<p>当文件名或变量名存储在字符串中时，可以使用SAVE函数如SAVE(&#8216;filename&#8217;,'var1&#8242;,&#8217;var2&#8242;)。</p>
<p>举例：save sinwave.dat x -ASCII &#8212; 将变量x以ASCII格式保存到名为sinwave.dat的文件中</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/16/matlab_save/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>在TMS320C62x上实现扩展精度的复数基2FFT/IFFT算法</title>
		<link>http://ichaochao.com/2008/07/10/fft_in_c62x/</link>
		<comments>http://ichaochao.com/2008/07/10/fft_in_c62x/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 09:03:44 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[c6000]]></category>
		<category><![CDATA[DSP]]></category>

		<guid isPermaLink="false">http://ichaochao.com/?p=159</guid>
		<description><![CDATA[本文翻译自TI的文档《spra696a_Extended-Precision Complex Radix-2 FFT_IFFT Implemented on TMS320C62x.pdf》。&#8212;&#8212;哎，没过CET4，看E文就是累啊！
&#8212; 文首预览 &#8212;
定点DSP有限的动态范围导致在计算FFT时精度不够。这是因为使用了量化和缩放来防止输出溢出。因此，会需要使用扩展精度来执行计算，特别是对于大尺寸的FFT。高度优化的扩展精度的FFT和IFFT汇编程序，可以在TMS320C62X上，通过适度增加运行时间来提高运算精度。
目录：
1.    快速傅立叶变换FFT
2.    快速傅立叶反变换IFFT
3.    精度扩展的需要
4.    C62x上的扩展精度乘法
5.    FFT的实现
6.     IFFT的实现
7.    比例缩放问题
8.    误差估计
9.    基准（Benchmarks）
10.    输出位反转
11.    代码
12.    参考文档

注：本人E文极差，请慎重考虑是否要下载全文！
全文下载地址
]]></description>
			<content:encoded><![CDATA[<p>本文翻译自TI的文档《spra696a_Extended-Precision Complex Radix-2 FFT_IFFT Implemented on TMS320C62x.pdf》。&#8212;&#8212;哎，没过CET4，看E文就是累啊！</p>
<p class="MsoNormal">&#8212; 文首预览 &#8212;</p>
<p class="MsoNormal"><span style="宋体;">定点</span><span>DSP</span><span style="宋体;">有限的动态范围导致在计算</span><span>FFT</span><span style="宋体;">时精度不够。这是因为使用了量化和缩放来防止输出溢出。因此，会需要使用扩展精度来执行计算，特别是对于大尺寸的</span><span>FFT</span><span style="宋体;">。高度优化的扩展精度的</span><span>FFT</span><span style="宋体;">和</span><span>IFFT</span><span style="宋体;">汇编程序，可以在</span><span>TMS320C62X</span><span style="宋体;">上，通过适度增加运行时间来提高运算精度。</span></p>
<p class="MsoNormal"><span id="more-159"></span>目录：</p>
<p class="MsoNormal">1.    快速傅立叶变换FFT<br />
2.    快速傅立叶反变换IFFT<br />
3.    精度扩展的需要<br />
4.    C62x上的扩展精度乘法<br />
5.    FFT的实现<br />
6.     IFFT的实现<br />
7.    比例缩放问题<br />
8.    误差估计<br />
9.    基准（Benchmarks）<br />
10.    输出位反转<br />
11.    代码<br />
12.    参考文档</p>
<p class="MsoNormal">
<p class="MsoNormal">注：本人E文极差，请慎重考虑是否要下载全文！</p>
<p><a href="http://www.box.net/shared/pbv0rhtcs4" target="_blank">全文下载地址</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/10/fft_in_c62x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DSP中数的定标</title>
		<link>http://ichaochao.com/2008/07/03/dsp_q15/</link>
		<comments>http://ichaochao.com/2008/07/03/dsp_q15/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 08:03:13 +0000</pubDate>
		<dc:creator>chaochao</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[DSP]]></category>
		<category><![CDATA[program]]></category>

		<guid isPermaLink="false">http://ichaochao.com/2008/07/03/dsp_q15/</guid>
		<description><![CDATA[在TI的文档&#60;spru402 _TMS320C62x DSP Library Programmer&#8217;s Reference&#62;中，提到了Q格式。关于这个，我手上的两本书，都没有提到，而TI的这个文档里也只是在附录里简单说明了一下。大意是：DSPLIB函数一般都使用Q15格式。其实这个Q15确切的说是Q0.15。格式是Qm.n，m指小数点前（即整数部分）的数的个数，n指小数点后（即小数部分）的数的个数，再加上最高位是符号位，这样Q15就是一个16位的word。它表示的范围是（1，-1）。它表示的数分辨率是2的-15次方，数是用2的补码来表示的。   

&#160;
如此，既然可以有Q.15，那也可以有Q.31，当然也可以有Q3.12这样形式的。可以看出，不同的Q所表示的数不仅范围不同，而且精度也不相同。Q越大，数值范围越小，但精度越高；相反，Q越小，数值范围越大，但精度就越低。范围与精度是一对不可调和的矛盾，实际应用中，只能视实际需要来取平衡。
有了Q格式，就可以用定点DSP来计算浮点数。   
&#8212;&#8212;&#8212;-&#160; 关于补码相关知识的温故知新 &#8212;&#8212;&#8212;-   
原码就是这个数本身的二进制形式。如：00000001 就是+1 10000001 就是-1。    反码表示法规定：正数的反码与其原码相同；负数的反码是对其原码逐位取反，但符号位除外。    补码表示法规定：正数的补码与其原码相同；负数的补码是在其反码的末位加1。
补码的意义：   （1）补码统一正0和负0    （2）补码中符号位要与有效值部分一起进行运算。    （3）使减法运算转换为加法运算。 [a-b]补=[a]补+[-b]补
链接1：关于补码的详细介绍
链接2：DSP定点算数运算
]]></description>
			<content:encoded><![CDATA[<p>在TI的文档&lt;spru402 _TMS320C62x DSP Library Programmer&#8217;s Reference&gt;中，提到了Q格式。关于这个，我手上的两本书，都没有提到，而TI的这个文档里也只是在附录里简单说明了一下。大意是：DSPLIB函数一般都使用Q15格式。其实这个Q15确切的说是Q0.15。格式是Qm.n，m指小数点前（即整数部分）的数的个数，n指小数点后（即小数部分）的数的个数，再加上最高位是符号位，这样Q15就是一个16位的word。它表示的范围是（1，-1）。它表示的数分辨率是2的-15次方，数是用2的补码来表示的。   </p>
<p><span id="more-156"></span></p>
<p>&#160;</p>
<p>如此，既然可以有Q.15，那也可以有Q.31，当然也可以有Q3.12这样形式的。可以看出，不同的Q所表示的数不仅范围不同，而且精度也不相同。Q越大，数值范围越小，但精度越高；相反，Q越小，数值范围越大，但精度就越低。范围与精度是一对不可调和的矛盾，实际应用中，只能视实际需要来取平衡。</p>
<p>有了Q格式，就可以用定点DSP来计算浮点数。   </p>
<p>&#8212;&#8212;&#8212;-&#160; 关于补码相关知识的温故知新 &#8212;&#8212;&#8212;-   </p>
<p>原码就是这个数本身的二进制形式。如：00000001 就是+1 10000001 就是-1。    <br />反码表示法规定：正数的反码与其原码相同；负数的反码是对其原码逐位取反，但符号位除外。    <br />补码表示法规定：正数的补码与其原码相同；负数的补码是在其反码的末位加1。</p>
<p>补码的意义：   <br />（1）补码统一正0和负0    <br />（2）补码中符号位要与有效值部分一起进行运算。    <br />（3）使减法运算转换为加法运算。 [a-b]补=[a]补+[-b]补</p>
<p>链接1：<a href="http://hi.baidu.com/maytao/blog/item/52fab4544ae1521e3a2935e3.html" target="_blank">关于补码的详细介绍</a></p>
<p>链接2：<a href="http://www.61ic.com/Article/FAQ/soft/200610/6791.html" target="_blank">DSP定点算数运算</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/03/dsp_q15/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>FFT在C6000DSP上的仿真</title>
		<link>http://ichaochao.com/2008/07/01/fft_in_dsp/</link>
		<comments>http://ichaochao.com/2008/07/01/fft_in_dsp/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 09:04:00 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[假装爱摄影]]></category>
		<category><![CDATA[c6000]]></category>
		<category><![CDATA[CCS]]></category>
		<category><![CDATA[DSP]]></category>
		<category><![CDATA[fft]]></category>

		<guid isPermaLink="false">http://ichaochao.com/2008/07/01/fft_in_dsp/</guid>
		<description><![CDATA[经过一段时间的学习，今天在CCS内成功仿真了基2频域抽取FFT(radix2 DIF FFT)。
环境：CCS 3.1 + C6201 Device Simulator
仿真结果如下图：

全部代码在下面，为了描述简单，把所有函数写在了一起，实际运用中不应该这样做。另外位反转索引表和旋转因子表都是在里面实时生成的，实际运用时，应该做好表格后嵌入，或在编译时生成而不是运行时生成。
感谢 pacificxu 的教程，他貌似曾经是闻亭的高手。
#include &#8220;math.h&#8221;
/*========================================*/
/* GLOBAL CONSTANTS                                                          */
/*========================================*/
#define PI    3.14159265358979
#define N        2048
/*========================================*/
/* GLOBAL VARIABLES                                                          */
/*========================================*/
static short index1[64], w1[N];
static short x1[N*2];
static int x2[N];
int i;
void DSP_radix2(int n, short *restrict xy, const short *restrict w)
{
short n1,n2,ie,ia,i,j,k,l;
short xt,yt,c,s;
n2 = n;
ie = 1;
for (k=n; k &#62; 1; k = (k &#62;&#62; 1) )
{
n1 = <a href="http://ichaochao.com/2008/07/01/fft_in_dsp/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>经过一段时间的学习，今天在CCS内成功仿真了基2频域抽取FFT(radix2 DIF FFT)。</p>
<p>环境：CCS 3.1 + C6201 Device Simulator</p>
<p>仿真结果如下图：</p>
<p><span id="more-155"></span><a href="http://ichaochao.com/wp-content/uploads/2008/07/fft-timewave.jpg"><img style="0px" src="http://ichaochao.com/wp-content/uploads/2008/07/fft-timewave-thumb.jpg" border="0" alt="fft_timewave" width="244" height="169" /></a><a href="http://ichaochao.com/wp-content/uploads/2008/07/fft-freqwave.jpg"><img style="0px" src="http://ichaochao.com/wp-content/uploads/2008/07/fft-freqwave-thumb.jpg" border="0" alt="fft_freqwave" width="244" height="168" /></a></p>
<p>全部代码在下面，为了描述简单，把所有函数写在了一起，实际运用中不应该这样做。另外位反转索引表和旋转因子表都是在里面实时生成的，实际运用时，应该做好表格后嵌入，或在编译时生成而不是运行时生成。</p>
<p>感谢 pacificxu 的教程，他貌似曾经是闻亭的高手。</p>
<p>#include &#8220;math.h&#8221;<br />
/*========================================*/<br />
/* GLOBAL CONSTANTS                                                          */<br />
/*========================================*/</p>
<p>#define PI    3.14159265358979<br />
#define N        2048</p>
<p>/*========================================*/<br />
/* GLOBAL VARIABLES                                                          */<br />
/*========================================*/<br />
static short index1[64], w1[N];<br />
static short x1[N*2];<br />
static int x2[N];<br />
int i;</p>
<p>void DSP_radix2(int n, short *restrict xy, const short *restrict w)<br />
{<br />
short n1,n2,ie,ia,i,j,k,l;<br />
short xt,yt,c,s;<br />
n2 = n;<br />
ie = 1;<br />
for (k=n; k &gt; 1; k = (k &gt;&gt; 1) )<br />
{<br />
n1 = n2;<br />
n2 = n2&gt;&gt;1;<br />
ia = 0;<br />
for (j=0; j &lt; n2; j++)<br />
{<br />
c = w[2*ia];<br />
s = w[2*ia+1];<br />
ia = ia + ie;<br />
for (i=j; i &lt; n; i += n1)<br />
{<br />
l = i + n2;<br />
xt      = xy[2*l] &#8211; xy[2*i];<br />
xy[2*i] = xy[2*i] + xy[2*l];<br />
yt      = xy[2*l+1] &#8211; xy[2*i+1];<br />
xy[2*i+1] = xy[2*i+1] + xy[2*l+1];<br />
xy[2*l]   = (c*xt + s*yt)&gt;&gt;15;<br />
xy[2*l+1] = (c*yt &#8211; s*xt)&gt;&gt;15;<br />
}<br />
}<br />
ie = ie&lt;&lt;1;<br />
}<br />
}<br />
void DSP_bitrev_cplx(int *x, short *index, int nx)<br />
{<br />
int     i;<br />
short       i0, i1, i3;<br />
short       j0, j1, j3;<br />
int     xi0, xi1, xi3;<br />
int     xj0, xj1, xj3;<br />
short       t;<br />
int     a, b, ia, ib, ibs;<br />
int     mask;<br />
int     nbits, nbot, ntop, ndiff, n2, halfn;<br />
nbits = 0;<br />
i = nx;<br />
while (i &gt; 1)<br />
{<br />
i = i &gt;&gt; 1;<br />
nbits++;<br />
}</p>
<p>nbot    = nbits &gt;&gt; 1;<br />
ndiff   = nbits &amp; 1;<br />
ntop    = nbot + ndiff;<br />
n2      = 1 &lt;&lt; ntop;<br />
mask    = n2 &#8211; 1;<br />
halfn   = nx &gt;&gt; 1;<br />
for (i0 = 0; i0 &lt; halfn; i0 += 2)<br />
{<br />
b   = i0 &amp; mask;<br />
a   = i0 &gt;&gt; nbot;<br />
if (!b) ia  = index[a];<br />
ib  = index[b];<br />
ibs = ib &lt;&lt; nbot;<br />
j0  = ibs + ia;<br />
t   = i0 &lt; j0;<br />
xi0 = x[i0];<br />
xj0 = x[j0];</p>
<p>if (t){x[i0] = xj0;<br />
x[j0] = xi0;}</p>
<p>i1  = i0 + 1;<br />
j1  = j0 + halfn;<br />
xi1 = x[i1];<br />
xj1 = x[j1];<br />
x[i1] = xj1;<br />
x[j1] = xi1;</p>
<p>i3  = i1 + halfn;<br />
j3  = j1 + 1;<br />
xi3 = x[i3];<br />
xj3 = x[j3];<br />
if (t){x[i3] = xj3;<br />
x[j3] = xi3;}<br />
}<br />
}<br />
void bitrev_index(short *index, int n)<br />
{<br />
int   i, j, k, radix = 2;<br />
short nbits, nbot, ntop, ndiff, n2, raddiv2;<br />
nbits = 0;<br />
i = n;<br />
while (i &gt; 1)<br />
{<br />
i = i &gt;&gt; 1;<br />
nbits++;<br />
}<br />
raddiv2 = radix &gt;&gt; 1;<br />
nbot    = nbits &gt;&gt; raddiv2;<br />
nbot    = nbot &lt;&lt; raddiv2 &#8211; 1;<br />
ndiff   = nbits &amp; raddiv2;<br />
ntop    = nbot + ndiff;<br />
n2      = 1 &lt;&lt; ntop;<br />
index[0] = 0;<br />
for ( i = 1, j = n2/radix + 1; i &lt; n2 &#8211; 1; i++)<br />
{<br />
index[i] = j &#8211; 1;<br />
for (k = n2/radix; k*(radix-1) &lt; j; k /= radix)<br />
j -= k*(radix-1);<br />
j += k;<br />
}<br />
index[n2 - 1] = n2 &#8211; 1;<br />
}<br />
/*===================================*/<br />
/* MAIN()                                                                    */<br />
/*===================================*/<br />
void main()</p>
<p>{<br />
double delta;</p>
<p>/*======== init the index table for FFT bitrev =====*/</p>
<p>bitrev_index(index1, N);</p>
<p>/*======== init the FFT coeficients =====*/<br />
delta = 2*PI/N;<br />
for (i=0;i&lt;N/2;i++)<br />
{<br />
w1[2*i] = 32767*(-cos((double)i*delta));<br />
w1[2*i+1] = 32767*(-sin((double)i*delta));<br />
}</p>
<p>/*======== init the input data =====*/<br />
for (i=0;i&lt;N;i++)<br />
{<br />
x1[2*i] = (short)((cos(PI*i/20.0)+cos(PI*i/10.0)+cos(PI*i/5.0))*0&#215;80);<br />
x1[2*i+1] = 0;<br />
}<br />
/*======== implement FFT =====*/</p>
<p>DSP_radix2(N, x1, w1);<br />
for (i=0; i&lt;N; i++)<br />
{<br />
x2[i] = sqrt(x1[2*i]*x1[2*i]+x1[2*i+1]*x1[2*i+1]);  //&#8212;?<br />
}</p>
<p>/*======== bitrev =====*/</p>
<p>DSP_bitrev_cplx(x2, index1, N);<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/01/fft_in_dsp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CCS的一些问题(转)</title>
		<link>http://ichaochao.com/2008/07/01/ccs_problem/</link>
		<comments>http://ichaochao.com/2008/07/01/ccs_problem/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 02:15:40 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[CCS]]></category>
		<category><![CDATA[DSP]]></category>

		<guid isPermaLink="false">http://ichaochao.com/?p=150</guid>
		<description><![CDATA[来自DSP交流网
CCS版本:V3.1
1.run和animate的区别
如果没有断点的话,这两个没区别.
如果有断点,那么run的时候到断点会停止,直到再次按run或者F5才继续执行.
而Animate到断点的时候,会停一小会,将所有窗口刷新一遍,然后就继续执行

一般就是在要看数据变化的时候,先把曲线画出来,然后在改变数据的循环里面设个断点,然后用animate,就能看到图片动态改变了,可以参考 Help-&#62;tutorial里面的&#8221;Code Composer Studio? IDE&#8221;-&#62;&#8221;Using Debug Tools&#8221;这一个教程
2.Probe Point 和Breakpoints的区别和联系
共性:他们都会暂停程序运行
区别:
1.Probe Point暂停程序,执行一个设定的任务(如File I/O),然后继续执行程序.而BreakPoint暂停后必须手动继续(当用run的时候)
2.BreakPoints会刷新所有窗口,而ProbePoint不会
3.Probe Point可以执行一些任务(如File I/O),而BreakPoints就是纯粹的停止.
3.阻塞(blocked)和中断(interrupt)的区别和联系
共性:他们都能停止一个tsk(任务,具体见我的另一篇文章:关于tsk和mbx)的执行
区别:
1.只有tsk(任务)能被阻塞,而swi(软中断)和hwi(硬中断)不能阻塞,只能中断
2.停止的原因不一样,阻塞是在某些条件不满足的时候停止tsk,中断是因为有高优先级的事情要做而停止
3.恢复运行的条件不一样,阻塞是要等到原来不满足的条件满足后才能继续,而中断是要等高优先级的任务返回后才继续执行.
4.阻塞改变tsk的任务队列,而中断一个tsk不会改变tsk的任务队列.
举个现实的例子:
如果你在写作业,写着写着,碰到一道很难的题,你百思不得其解,这个时候写作业的这个tsk就被阻塞了,只有等到你想出来这道题怎么做,才能继续做下去.
另外一种情况,还是在写作业,突然门铃响了,你必须去开门,那写作业这个tsk就被中断了,你开完门就能回来继续写作业.
4.LOG_printf和printf的区别和联系
共性:都是用于输出一些内容,一般用于显示一些调试信息,而且可以格式化输出,比如用&#8217;%d&#8217;输出整数
区别:
1.输出目标不同,printf输出到output窗口,而LOG_printf输出到BIOS的log窗口
2.汇编指令条数不同,printf需要上万条汇编指令,而LOG_printf只要30多条汇编指令,因此LOG_printf的运行速度比printf要快的多,一般在实时系统中,都使用LOG_printf来输出,这样对系统的实时性影响才不大
3.参数个数不同,printf后面的参数个数可以有很多个(具体多少个没测试过),而LOG_printf后面最多只能有4个参数,第一个是写入的地址,第二个是字符串,后面最多加上两个格式化输出的数据,这两个数据还必须是整型,或者指针,或者常量字符串
4.可以输出的格式不同,printf有很多的格式,而LOG_printf只有有限的几种.(%d整型,%x无符号16进制数,%o无符号8进制数,%s常量字符串,%p指针)
5.LOG_printf输出的长度受设定的buffer大小限制,如果超出buffer大小,根据设置的不同,可以是停止输出,或者覆盖原来的内容
6.LOG_printf的优先级比较低,可能是在KNL层,只有系统比较空闲的时候,才会输出,而printf是必然会输出.(比如在一个i=1到 100的循环中,用printf就会输出100个数,而用LOG_printf就只会输出一部分数,而且在没有碰到断点的时候,根本不会输出,因为他的优 先级相当低,只有在走到断点的时候,系统才允许他执行.)
5.设置tab的宽度
1.打开&#8221;Option -&#62; Editor -&#62; language&#8221;
2.在左边的File Type里面选择要修改的扩展名(CCS中每种不同扩展名的文件都能设置不同的tab宽度,而不是象一般的代码编辑器,可以全局设置)
3.在右边顶部选择&#8221;Tabs/Indenting&#8221;选项卡
4.在&#8221;Tab Columns&#8221;下面的框中输入&#8221;3 5&#8243;(默认值是5 9,注意两个数值中间有空格)
5.点击OK按钮
解释一下&#8221;3 5&#8243;的意义,第一个数字等于在一行的最开头按Tab键时跳过的列数加1,第二个数减去第一个数的结果,等于除去每行最开头外的Tab的宽度.
设置成&#8221;3 5&#8243;表示如果在每行开头按Tab,缩进3-1=2列,而其它地方的缩进是5-3=2列,也就是无论什么地方Tab键的宽度都是2列.
个人觉得,CCS的这个设置Tab键宽度挺有意思的.
]]></description>
			<content:encoded><![CDATA[<p>来自<a href="http://www.hellodsp.com/" target="_blank">DSP交流网</a><br />
CCS版本:V3.1</p>
<p>1.run和animate的区别</p>
<p>如果没有断点的话,这两个没区别.<br />
如果有断点,那么run的时候到断点会停止,直到再次按run或者F5才继续执行.<br />
而Animate到断点的时候,会停一小会,将所有窗口刷新一遍,然后就继续执行</p>
<p><span id="more-150"></span></p>
<p>一般就是在要看数据变化的时候,先把曲线画出来,然后在改变数据的循环里面设个断点,然后用animate,就能看到图片动态改变了,可以参考 Help-&gt;tutorial里面的&#8221;Code Composer Studio? IDE&#8221;-&gt;&#8221;Using Debug Tools&#8221;这一个教程</p>
<p>2.Probe Point 和Breakpoints的区别和联系</p>
<p>共性:他们都会暂停程序运行</p>
<p>区别:</p>
<p>1.Probe Point暂停程序,执行一个设定的任务(如File I/O),然后继续执行程序.而BreakPoint暂停后必须手动继续(当用run的时候)<br />
2.BreakPoints会刷新所有窗口,而ProbePoint不会<br />
3.Probe Point可以执行一些任务(如File I/O),而BreakPoints就是纯粹的停止.</p>
<p>3.阻塞(blocked)和中断(interrupt)的区别和联系</p>
<p>共性:他们都能停止一个tsk(任务,具体见我的另一篇文章:关于tsk和mbx)的执行</p>
<p>区别:</p>
<p>1.只有tsk(任务)能被阻塞,而swi(软中断)和hwi(硬中断)不能阻塞,只能中断</p>
<p>2.停止的原因不一样,阻塞是在某些条件不满足的时候停止tsk,中断是因为有高优先级的事情要做而停止</p>
<p>3.恢复运行的条件不一样,阻塞是要等到原来不满足的条件满足后才能继续,而中断是要等高优先级的任务返回后才继续执行.</p>
<p>4.阻塞改变tsk的任务队列,而中断一个tsk不会改变tsk的任务队列.</p>
<p>举个现实的例子:<br />
如果你在写作业,写着写着,碰到一道很难的题,你百思不得其解,这个时候写作业的这个tsk就被阻塞了,只有等到你想出来这道题怎么做,才能继续做下去.</p>
<p>另外一种情况,还是在写作业,突然门铃响了,你必须去开门,那写作业这个tsk就被中断了,你开完门就能回来继续写作业.</p>
<p>4.LOG_printf和printf的区别和联系</p>
<p>共性:都是用于输出一些内容,一般用于显示一些调试信息,而且可以格式化输出,比如用&#8217;%d&#8217;输出整数</p>
<p>区别:</p>
<p>1.输出目标不同,printf输出到output窗口,而LOG_printf输出到BIOS的log窗口</p>
<p>2.汇编指令条数不同,printf需要上万条汇编指令,而LOG_printf只要30多条汇编指令,因此LOG_printf的运行速度比printf要快的多,一般在实时系统中,都使用LOG_printf来输出,这样对系统的实时性影响才不大</p>
<p>3.参数个数不同,printf后面的参数个数可以有很多个(具体多少个没测试过),而LOG_printf后面最多只能有4个参数,第一个是写入的地址,第二个是字符串,后面最多加上两个格式化输出的数据,这两个数据还必须是整型,或者指针,或者常量字符串</p>
<p>4.可以输出的格式不同,printf有很多的格式,而LOG_printf只有有限的几种.(%d整型,%x无符号16进制数,%o无符号8进制数,%s常量字符串,%p指针)</p>
<p>5.LOG_printf输出的长度受设定的buffer大小限制,如果超出buffer大小,根据设置的不同,可以是停止输出,或者覆盖原来的内容</p>
<p>6.LOG_printf的优先级比较低,可能是在KNL层,只有系统比较空闲的时候,才会输出,而printf是必然会输出.(比如在一个i=1到 100的循环中,用printf就会输出100个数,而用LOG_printf就只会输出一部分数,而且在没有碰到断点的时候,根本不会输出,因为他的优 先级相当低,只有在走到断点的时候,系统才允许他执行.)</p>
<p>5.设置tab的宽度</p>
<p>1.打开&#8221;Option -&gt; Editor -&gt; language&#8221;<br />
2.在左边的File Type里面选择要修改的扩展名(CCS中每种不同扩展名的文件都能设置不同的tab宽度,而不是象一般的代码编辑器,可以全局设置)<br />
3.在右边顶部选择&#8221;Tabs/Indenting&#8221;选项卡<br />
4.在&#8221;Tab Columns&#8221;下面的框中输入&#8221;3 5&#8243;(默认值是5 9,注意两个数值中间有空格)<br />
5.点击OK按钮</p>
<p>解释一下&#8221;3 5&#8243;的意义,第一个数字等于在一行的最开头按Tab键时跳过的列数加1,第二个数减去第一个数的结果,等于除去每行最开头外的Tab的宽度.<br />
设置成&#8221;3 5&#8243;表示如果在每行开头按Tab,缩进3-1=2列,而其它地方的缩进是5-3=2列,也就是无论什么地方Tab键的宽度都是2列.</p>
<p>个人觉得,CCS的这个设置Tab键宽度挺有意思的.</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/01/ccs_problem/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C语言高效编程的几招(转)</title>
		<link>http://ichaochao.com/2008/07/01/c_program/</link>
		<comments>http://ichaochao.com/2008/07/01/c_program/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 00:09:56 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[program]]></category>

		<guid isPermaLink="false">http://ichaochao.com/?p=149</guid>
		<description><![CDATA[引 言：
编写高效简洁的C语言代码，是许多软件工程师追求的目标。本文就工作中的一些体会和经验做相关的阐述，不对的地方请各位指教。

第1招：以空间换时间
计算机程序中最大的矛盾是空间和时间的矛盾，那么，从这个角度出发逆向思维来考虑程序的效率问题，我们就有了解决问题的第1招——以空间换时间。
例如：字符串的赋值。
方法A，通常的办法：
#define LEN 32
char string1 [LEN];
memset (string1,0,LEN);
strcpy (string1,“This is a example!!”）;
方法B：
const char string2[LEN] =“This is a example!”;
char * cp;
cp = string2 ;
(使用的时候可以直接用指针来操作。)
从上面的例子可以看出，A和B的效率是不能比的。在同样的存储空间下，B直接使用指针就可以操作了，而A需要调用两个字符函数才能完成。B的缺点在于灵 活性没有A好。在需要频繁更改一个字符串内容的时候，A具有更好的灵活性；如果采用方法B，则需要预存许多字符串，虽然占用了大量的内存，但是获得了程序 执行的高效率。
如果系统的实时性要求很高，内存还有一些，那我推荐你使用该招数。
该招数的变招——使用宏函数而不是函数。举例如下：
方法C：
#define bwMCDR2_ADDRESS 4
#define bsMCDR2_ADDRESS 17
int BIT_MASK(int __bf)
{
return ((1U &#60;&#60; (bw ## __bf)) &#8211; 1) &#60;&#60; (bs ## __bf);
}
void SET_BITS(int __dst, int __bf, int __val)
{
__dst = ((__dst) &#38; ~(BIT_MASK(__bf))) &#124; \
(((__val) &#60;&#60; (bs <a href="http://ichaochao.com/2008/07/01/c_program/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p class="p4"><strong>引 言：</strong><br />
编写高效简洁的C语言代码，是许多软件工程师追求的目标。本文就工作中的一些体会和经验做相关的阐述，不对的地方请各位指教。<br />
<span id="more-149"></span></p>
<p class="p4"><strong>第1招：以空间换时间</strong></p>
<p class="p4">计算机程序中最大的矛盾是空间和时间的矛盾，那么，从这个角度出发逆向思维来考虑程序的效率问题，我们就有了解决问题的第1招——以空间换时间。<br />
例如：字符串的赋值。<br />
方法A，通常的办法：<br />
#define LEN 32<br />
char string1 [LEN];<br />
memset (string1,0,LEN);<br />
strcpy (string1,“This is a example!!”）;<br />
方法B：<br />
const char string2[LEN] =“This is a example!”;<br />
char * cp;<br />
cp = string2 ;<br />
(使用的时候可以直接用指针来操作。)</p>
<p class="p4">从上面的例子可以看出，A和B的效率是不能比的。在同样的存储空间下，B直接使用指针就可以操作了，而A需要调用两个字符函数才能完成。B的缺点在于灵 活性没有A好。在需要频繁更改一个字符串内容的时候，A具有更好的灵活性；如果采用方法B，则需要预存许多字符串，虽然占用了大量的内存，但是获得了程序 执行的高效率。</p>
<p class="p4">如果系统的实时性要求很高，内存还有一些，那我推荐你使用该招数。</p>
<p class="p4">该招数的变招——使用宏函数而不是函数。举例如下：<br />
方法C：<br />
#define bwMCDR2_ADDRESS 4<br />
#define bsMCDR2_ADDRESS 17<br />
int BIT_MASK(int __bf)<br />
{<br />
return ((1U &lt;&lt; (bw ## __bf)) &#8211; 1) &lt;&lt; (bs ## __bf);<br />
}<br />
void SET_BITS(int __dst, int __bf, int __val)<br />
{<br />
__dst = ((__dst) &amp; ~(BIT_MASK(__bf))) | \<br />
(((__val) &lt;&lt; (bs ## __bf)) &amp; (BIT_MASK(__bf))))<br />
}</p>
<p class="p4">SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);<br />
方法D：<br />
#define bwMCDR2_ADDRESS 4<br />
#define bsMCDR2_ADDRESS 17<br />
#define bmMCDR2_ADDRESS BIT_MASK(MCDR2_ADDRESS)<br />
#define BIT_MASK(__bf) (((1U &lt;&lt; (bw ## __bf)) &#8211; 1) &lt;&lt; (bs ## __bf))<br />
#define SET_BITS(__dst, __bf, __val) \<br />
((__dst) = ((__dst) &amp; ~(BIT_MASK(__bf))) | \<br />
(((__val) &lt;&lt; (bs ## __bf)) &amp; (BIT_MASK(__bf))))</p>
<p class="p4">SET_BITS(MCDR2, MCDR2_ADDRESS, RegisterNumber);</p>
<p class="p4">函数和宏函数的区别就在于，宏函数占用了大量的空间，而函数占用了时间。大家要知道的是，函数调用是要使用系统的栈来保存数据的，如果编译器里有栈检查 选项，一般在函数的头会嵌入一些汇编语句对当前栈进行检查；同时，CPU也要在函数调用时保存和恢复当前的现场，进行压栈和弹栈操作，所以，函数调用需要 一些CPU时间。而宏函数不存在这个问题。宏函数仅仅作为预先写好的代码嵌入到当前程序，不会产生函数调用，所以仅仅是占用了空间，在频繁调用同一个宏函 数的时候，该现象尤其突出。</p>
<p class="p4">D方法是我看到的最好的置位操作函数，是ARM公司源码的一部分，在短短的三行内实现了很多功能，几乎涵盖了所有的位操作功能。C方法是其变体，其中滋味还需大家仔细体会。</p>
<p class="p4"><strong>第2招：数学方法解决问题</strong></p>
<p class="p4">现在我们演绎高效C语言编写的第二招——采用数学方法来解决问题。</p>
<p class="p4">数学是计算机之母，没有数学的依据和基础，就没有计算机的发展，所以在编写程序的时候，采用一些数学方法会对程序的执行效率有数量级的提高。<br />
举例如下，求 1~100的和。<br />
方法E<br />
int I , j;<br />
for (I = 1 ;I&lt;=100; I ++）{<br />
j += I;<br />
}<br />
方法F<br />
int I;<br />
I = (100 * (1+100)) / 2</p>
<p class="p4">这个例子是我印象最深的一个数学用例，是我的计算机启蒙老师考我的。当时我只有小学三年级，可惜我当时不知道用公式 N×（N+1）/ 2 来解决这个问题。方法E循环了100次才解决问题，也就是说最少用了100个赋值，100个判断，200个加法（I和j）；而方法F仅仅用了1个加法，1 次乘法，1次除法。效果自然不言而喻。所以，现在我在编程序的时候，更多的是动脑筋找规律，最大限度地发挥数学的威力来提高程序运行的效率。</p>
<p class="p4"><strong>第3招：使用位操作</strong></p>
<p class="p4">实现高效的C语言编写的第三招——使用位操作，减少除法和取模的运算。</p>
<p class="p4">在计算机程序中，数据的位是可以操作的最小数据单位，理论上可以用“位运算”来完成所有的运算和操作。一般的位操作是用来控制硬件的，或者做数据变换使用，但是，灵活的位操作可以有效地提高程序运行的效率。举例如下：<br />
方法G<br />
int I,J;<br />
I = 257 /8;<br />
J = 456 % 32;<br />
方法H<br />
int I,J;<br />
I = 257 &gt;&gt;3;<br />
J = 456 &#8211; (456 &gt;&gt; 4 &lt;&lt; 4);</p>
<p class="p4">在字面上好像H比G麻烦了好多，但是，仔细查看产生的汇编代码就会明白，方法G调用了基本的取模函数和除法函数，既有函数调用，还有很多汇编代码和寄存 器参与运算；而方法H则仅仅是几句相关的汇编，代码更简洁，效率更高。当然，由于编译器的不同，可能效率的差距不大，但是，以我目前遇到的MS C ,ARM C 来看，效率的差距还是不小。相关汇编代码就不在这里列举了。<br />
运用这招需要注意的是，因为CPU的不同而产生的问题。比如说，在PC上用这招编写的程序，并在PC上调试通过，在移植到一个16位机平台上的时候，可能会产生代码隐患。所以只有在一定技术进阶的基础下才可以使用这招。</p>
<p class="p4"><strong>第4招：汇编嵌入</strong></p>
<p class="p4">高效C语言编程的必杀技，第四招——嵌入汇编。</p>
<p class="p4">“在熟悉汇编语言的人眼里，C语言编写的程序都是垃圾”。这种说法虽然偏激了一些，但是却有它的道理。汇编语言是效率最高的计算机语言，但是，不可能靠着它来写一个操作系统吧?所以，为了获得程序的高效率，我们只好采用变通的方法 ——嵌入汇编，混合编程。</p>
<p class="p4">举例如下，将数组一赋值给数组二,要求每一字节都相符。<br />
char string1[1024],string2[1024];<br />
方法I<br />
int I;<br />
for (I =0 ;I&lt;1024;I++)<br />
*(string2 + I) = *(string1 + I)<br />
方法J<br />
#ifdef _PC_<br />
int I;<br />
for (I =0 ;I&lt;1024;I++)<br />
*(string2 + I) = *(string1 + I);<br />
#else<br />
#ifdef _ARM_<br />
__asm<br />
{<br />
MOV R0,string1<br />
MOV R1,string2<br />
MOV R2,#0<br />
loop:<br />
LDMIA R0!, [R3-R11]<br />
STMIA R1!, [R3-R11]<br />
ADD R2,R2,#8<br />
CMP R2, #400<br />
BNE loop<br />
}<br />
#endif</p>
<p class="p4">方法I是最常见的方法，使用了1024次循环；方法J则根据平台不同做了区分，在ARM平台下，用嵌入汇编仅用128次循环就完成了同样的操作。这里有 朋友会说，为什么不用标准的内存拷贝函数呢?这是因为在源数据里可能含有数据为0的字节，这样的话，标准库函数会提前结束而不会完成我们要求的操作。这个 例程典型应用于LCD数据的拷贝过程。根据不同的CPU，熟练使用相应的嵌入汇编，可以大大提高程序执行的效率。</p>
<p class="p4">虽然是必杀技，但是如果轻易使用会付出惨重的代价。这是因为，使用了嵌入汇编，便限制了程序的可移植性，使程序在不同平台移植的过程中，卧虎藏龙，险象环生！同时该招数也与现代软件工程的思想相违背，只有在迫不得已的情况下才可以采用。切记，切记。</p>
<p class="p4">使用C语言进行高效率编程，我的体会仅此而已。在此以本文抛砖引玉，还请各位高手共同切磋。希望各位能给出更好的方法，大家一起提高我们的编程技巧。</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/07/01/c_program/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>计算机主板更换电容注意事项</title>
		<link>http://ichaochao.com/2008/06/13/mainboard_of_pc/</link>
		<comments>http://ichaochao.com/2008/06/13/mainboard_of_pc/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 05:58:43 +0000</pubDate>
		<dc:creator>beethoven</dc:creator>
				<category><![CDATA[假装懂技术]]></category>
		<category><![CDATA[挨踢]]></category>

		<guid isPermaLink="false">http://ichaochao.com/2008/06/13/%e8%ae%a1%e7%ae%97%e6%9c%ba%e4%b8%bb%e6%9d%bf%e6%9b%b4%e6%8d%a2%e7%94%b5%e5%ae%b9%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9/</guid>
		<description><![CDATA[对于一些使用时间较长的计算机，常常会出现无故重启、死机等现象。如经更换（插拔）显卡、内存、CPU之后仍未解的话，建议仔细观察一下主板上的电解电容。相对于现在大量使用的固态电容，老型号的主板大多仍使用的是常规铝电解电容，这类电容使用电解液，在长时间使用后会出现电解液干涸或漏液。如果你看到主板上的电容顶部鼓起来，或电容附近有黄褐色粉末，那就是这个电容漏液了。漏液会造成电容容量下降，从而使得电容的滤波能力下降，由于这一类电容通常位于CPU附近，由此带来的直接后果就是CPU工作不稳定。

更换电容及可解决此类问题。前日帮朋友更换一块ABIT的主板上的电容，这块主板使用毒龙600的CPU（非常古老），在更换过程中略有心得，总结一下。
1.购买的新电容最好和原电容在容量耐压和体积上一样，如买不到可买容量稍大耐压稍高的，但要注意体积不能过大。
2.拆除漏液电容。由于计算机主板为多层印制板，内有大面积铜皮层，会导致散热加快，因此需要用烙铁在电容引脚焊盘上加热较长时间，可上点锡以加快局部热传导。切勿用烙铁头使劲戳焊盘，容易弄坏焊盘。
3.如果有把握控制温度的话，也可以用热风枪，否则还是建议不用，因为非常容易把印制板烧焦。
4.拆除所有需更换电容后，需要对焊盘通孔以去除焊盘孔中的焊锡，同样的由于热传导非常快，吸锡带无用武之地，而气压式吸锡枪极易把焊盘吸下来，因此也不能使用。只能用烙铁对焊盘加热，同时用通针通焊盘孔，动作要温柔，切忌猛戳猛拽，要是焊盘掉了，那这主板也差不多废了。
5.做完上面这步后，下面就简单了，把新电容焊上（注意极性），用酒精清理印制板即可。
]]></description>
			<content:encoded><![CDATA[<p>对于一些使用时间较长的计算机，常常会出现无故重启、死机等现象。如经更换（插拔）显卡、内存、CPU之后仍未解的话，建议仔细观察一下主板上的电解电容。相对于现在大量使用的固态电容，老型号的主板大多仍使用的是常规铝电解电容，这类电容使用电解液，在长时间使用后会出现电解液干涸或漏液。如果你看到主板上的电容顶部鼓起来，或电容附近有黄褐色粉末，那就是这个电容漏液了。漏液会造成电容容量下降，从而使得电容的滤波能力下降，由于这一类电容通常位于CPU附近，由此带来的直接后果就是CPU工作不稳定。<br />
<span id="more-116"></span></p>
<p>更换电容及可解决此类问题。前日帮朋友更换一块ABIT的主板上的电容，这块主板使用毒龙600的CPU（非常古老），在更换过程中略有心得，总结一下。</p>
<p>1.购买的新电容最好和原电容在容量耐压和体积上一样，如买不到可买容量稍大耐压稍高的，但要注意体积不能过大。</p>
<p>2.拆除漏液电容。由于计算机主板为多层印制板，内有大面积铜皮层，会导致散热加快，因此需要用烙铁在电容引脚焊盘上加热较长时间，可上点锡以加快局部热传导。切勿用烙铁头使劲戳焊盘，容易弄坏焊盘。</p>
<p>3.如果有把握控制温度的话，也可以用热风枪，否则还是建议不用，因为非常容易把印制板烧焦。</p>
<p>4.拆除所有需更换电容后，需要对焊盘通孔以去除焊盘孔中的焊锡，同样的由于热传导非常快，吸锡带无用武之地，而气压式吸锡枪极易把焊盘吸下来，因此也不能使用。只能用烙铁对焊盘加热，同时用通针通焊盘孔，动作要温柔，切忌猛戳猛拽，要是焊盘掉了，那这主板也差不多废了。</p>
<p>5.做完上面这步后，下面就简单了，把新电容焊上（注意极性），用酒精清理印制板即可。</p>
]]></content:encoded>
			<wfw:commentRss>http://ichaochao.com/2008/06/13/mainboard_of_pc/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
	</channel>
</rss>

