找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7527|回復(fù): 4
收起左側(cè)

[求助]AD轉(zhuǎn)換結(jié)果輸出到1602上亂碼

[復(fù)制鏈接]
ID:27772 發(fā)表于 2011-1-12 01:09 | 顯示全部樓層 |閱讀模式

代碼如下,第一行正常顯示,第二行亂碼

 

  1. <br>1 #include<STC12C5A60S2.H> <br>2 #include<intrins.h> <br>3 <br>4 #define uchar unsigned char <br>5 #define uint unsigned int <br>6 <br>7 unsigned int temp1,sh1,ge1,n1,m1; <br>8 unsigned char ad_result_data[10]; //AD轉(zhuǎn)換高八位 <br>9 unsigned char ad_result_low2[10]; //AD轉(zhuǎn)換低八位 <br>10 unsigned char ad_result_total[10]; //AD轉(zhuǎn)換總十位 <br>11 unsigned char ad_average_result; //AD轉(zhuǎn)換十次的平均值 <br>12 unsigned char Ain,Vin; <br>13 unsigned int temp1,sh1,ge1,n1,m1; <br>14 char tp=0; <br>15 <br>16 //===============================LCD1602接口定義===================== <br>17 <br>18 //定義引腳 <br>19 #define LCM_Data P0 //數(shù)據(jù)接口 <br>20 #define Busy 0x80 //用于檢測LCM狀態(tài)字中的Busy標(biāo)識 <br>21 sbit LCM_RS = P2^2; //寄存器選擇輸入端 <br>22 sbit LCM_RW = P2^3; //讀寫控制輸入端 <br>23 sbit LCM_E = P2^4; //使能信號輸入端 <br>24 <br>25 void WriteDataLCM(unsigned char WDLCM); <br>26 void WriteCommandLCM(unsigned char WCLCM,BuysC); <br>27 unsigned char ReadDataLCM(void); <br>28 unsigned char ReadStatusLCM(void); <br>29 void LCMInit(void); <br>30 void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData); <br>31 void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData); <br>32 void Delay5Ms(void); <br>33 void Delay400Ms(void); <br>34 void AD_initiate(); <br>35 void ADC_Power_On(); <br>36 void get_ad_result(); <br>37 void caiyangP10(); <br>38 <br>39 void main(void) <br>40 { <br>41 Delay400Ms(); //啟動等待,等LCM講入工作狀態(tài) <br>42 LCMInit(); //LCM初始化 <br>43 Delay5Ms(); //延時片刻(可不要) <br>44 AD_initiate(); //初始化 <br>45 ADC_Power_On(); //開AD電源 <br>46 <br>47 DisplayListChar(0, 0, "ADCTest"); <br>48 Delay5Ms(); <br>49 DisplayListChar(0, 1, "GAGA"); <br>50 //ReadDataLCM();//測試用句無意義 <br>51 while(1){ <br>52 &nbsp;&nbsp;&nbsp;&nbsp;caiyangP10(); <br>53 &nbsp;&nbsp;&nbsp;&nbsp;DisplayListChar(0, 1, Vin ); <br>54 &nbsp;&nbsp;&nbsp;&nbsp;Delay400Ms(); <br>55 } <br>56 } <br>57 <br>58 //寫數(shù)據(jù) <br>59 void WriteDataLCM(unsigned char WDLCM) <br>60 { <br>61 ReadStatusLCM(); //檢測忙 <br>62 LCM_Data = WDLCM; <br>63 LCM_RS = 1; <br>64 LCM_RW = 0; <br>65 LCM_E = 0; //若晶振速度太高可以在這后加小的延時 <br>66 LCM_E = 0; //延時 <br>67 LCM_E = 1; <br>68 } <br>69 <br>70 //寫指令 <br>71 void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC為0時忽略忙檢測 <br>72 { <br>73 if (BuysC) ReadStatusLCM(); //根據(jù)需要檢測忙 <br>74 LCM_Data = WCLCM; <br>75 LCM_RS = 0; <br>76 LCM_RW = 0; <br>77 LCM_E = 0; <br>78 LCM_E = 0; <br>79 LCM_E = 1; <br>80 } <br>81 <br>82 //讀數(shù)據(jù) <br>83 unsigned char ReadDataLCM(void) <br>84 { <br>85 LCM_RS = 1; <br>86 LCM_RW = 1; <br>87 LCM_E = 0; <br>88 LCM_E = 0; <br>89 LCM_E = 1; <br>90 return(LCM_Data); <br>91 } <br>92 <br>93 //讀狀態(tài) <br>94 unsigned char ReadStatusLCM(void) <br>95 { <br>96 LCM_Data = 0xFF; <br>97 LCM_RS = 0; <br>98 LCM_RW = 1; <br>99 LCM_E = 0; <br>100 LCM_E = 0; <br>101 LCM_E = 1; <br>102 while (LCM_Data &amp; Busy); //檢測忙信號 <br>103 return(LCM_Data); <br>104 } <br>105 <br>106 void LCMInit(void) //LCM初始化 <br>107 { <br>108 LCM_Data = 0; <br>109 WriteCommandLCM(0x38,0); //三次顯示模式設(shè)置,不檢測忙信號 <br>110 Delay5Ms(); <br>111 WriteCommandLCM(0x38,0); <br>112 Delay5Ms(); <br>113 WriteCommandLCM(0x38,0); <br>114 Delay5Ms(); <br>115 <br>116 WriteCommandLCM(0x38,1); //顯示模式設(shè)置,開始要求每次檢測忙信號 <br>117 WriteCommandLCM(0x08,1); //關(guān)閉顯示 <br>118 WriteCommandLCM(0x01,1); //顯示清屏 <br>119 WriteCommandLCM(0x06,1); // 顯示光標(biāo)移動設(shè)置 <br>120 WriteCommandLCM(0x0C,1); // 顯示開及光標(biāo)設(shè)置 <br>121 } <br>122 <br>123 //按指定位置顯示一個字符 <br>124 void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) <br>125 { <br>126 Y &amp;= 0x1; <br>127 X &amp;= 0xF; //限制X不能大于15,Y不能大于1 <br>128 if (Y) X |= 0x40; //當(dāng)要顯示第二行時地址碼+0x40; <br>129 X |= 0x80; // 算出指令碼 <br>130 WriteCommandLCM(X, 0); //這里不檢測忙信號,發(fā)送地址碼 <br>131 WriteDataLCM(DData); <br>132 } <br>133 <br>134 //按指定位置顯示一串字符 <br>135 void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData) <br>136 { <br>137 unsigned char ListLength; <br>138 <br>139 ListLength = 0; <br>140 Y &amp;= 0x1; <br>141 X &amp;= 0xF; //限制X不能大于15,Y不能大于1 <br>142 while (DData[ListLength]>0x20) //若到達(dá)字串尾則退出 <br>143 { <br>144 if (X <= 0xF) //X坐標(biāo)應(yīng)小于0xF <br>145 { <br>146 DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字符 <br>147 ListLength++; <br>148 X++; <br>149 } <br>150 } <br>151 } <br>152 <br>153 //5ms延時 <br>154 void Delay5Ms(void) <br>155 { <br>156 unsigned int TempCyc = 5552; <br>157 while(TempCyc--); <br>158 } <br>159 <br>160 //400ms延時 <br>161 void Delay400Ms(void) <br>162 { <br>163 unsigned char TempCycA = 5; <br>164 unsigned int TempCycB; <br>165 while(TempCycA--) <br>166 { <br>167 TempCycB=7269; <br>168 while(TempCycB--); <br>169 }; <br>170 } <br>171 <br>172 /************************AD轉(zhuǎn)換結(jié)束***********************/ <br>173 void AD_initiate() //初始化函數(shù) <br>174 { <br>175 ES=0; <br>176 TMOD=0x21; //定時計數(shù)器方式控制寄存器,"自動重裝,16位計數(shù)器". <br>177 SCON=0x50; //串行控制寄存器,方便在串口助手那觀察 <br>178 TH1=0xfa; <br>179 TL1=0xfa; <br>180 TR1=1; <br>181 } <br>182 <br>183 void ADC_Power_On() //AD轉(zhuǎn)換電 <br>184 { <br>185 ADC_CONTR |= 0x80; <br>186 Delay5Ms(); //必要的延時 <br>187 } <br>188 <br>189 void get_ad_result() //取AD結(jié)果函數(shù),它是十位AD轉(zhuǎn)換,每十次平均,最后取低八位作為AD采樣數(shù)據(jù) <br>190 { <br>191 uint i,q=0; <br>192 for(i=0;i<10;i++) <br>193 { <br>194 tp=0; <br>195 ADC_RES=0; //高八位數(shù)據(jù)清零,STC12C5A60S2 AD數(shù)據(jù)寄存名與STC12C54××系列不同 <br>196 ADC_RESL=0; //低兩位清零 <br>197 ADC_CONTR|=0x08; //啟動AD轉(zhuǎn)換 <br>198 while(!tp) //判斷AD轉(zhuǎn)換是否完成 <br>199 { <br>200 tp=0x10; <br>201 tp&amp;=ADC_CONTR; <br>202 } <br>203 ADC_CONTR&amp;=0xe7; <br>204 ad_average_result=ADC_RES; <br>205 q=q+ad_average_result; <br>206 } <br>207 ad_average_result=q/10; <br>208 //ad_average_result=ad_average_result*4*5000/1024; <br>209 } <br>210 /************************AD轉(zhuǎn)換結(jié)束***********************/ <br>211 <br>212 //---------------------電壓采樣程序------------------------- <br>213 <br>214 void caiyangP10() //測電壓 <br>215 { <br>216 P1M0|=0x01; //設(shè)P1_0為開漏模式 如: P1_0= #00000000B <br>217 P1M1|=0x01; <br>218 ADC_CONTR=0xe0; //設(shè)置P1.0為輸入AD轉(zhuǎn)換口 <br>219 Delay5Ms(); <br>220 get_ad_result(); //取轉(zhuǎn)換數(shù)據(jù) <br>221 Vin=ad_average_result; <br>222 }
復(fù)制代碼

[此貼子已經(jīng)被作者于2011-1-12 1:11:55編輯過]
回復(fù)

使用道具 舉報

ID:27770 發(fā)表于 2011-1-12 11:14 | 顯示全部樓層

建議你:

1.先解決 1602 顯示的問題,這個事情與是否 AD 或是其它內(nèi)容沒有直接聯(lián)系.做一個測試程序,讓 1602 先正常顯示 2 行字.(不算難的工作.)

2.上面解決后,把 AD 轉(zhuǎn)換結(jié)果拷貝到 1602 測試程序,看看是否正常.如果原來測試正常,后來不正常,則是 AD 數(shù)據(jù)可能格式不對,或者數(shù)據(jù)過大.(AD 數(shù)據(jù)原始是 HEX 碼,你需要處理后給 1602 .)

3.上面正常后,停止測試.把測試部分顯示移植到你項目去.----這樣不會再出錯了吧?

積木式的工作順序,特別是如果你第一次使用 1602 ,更應(yīng)該這么做.養(yǎng)成好習(xí)慣------其它新東西也是這種做法.

4.提示: 12C5A 的 AD 結(jié)果有 2 種選擇,它們組合  2 個數(shù)據(jù)字節(jié)得到 10BIT 數(shù)據(jù),檢查一下你的組合是否正確.(弄錯了就會大大超過 10BIT 非正常結(jié)果.)

僅供參考!

回復(fù)

使用道具 舉報

ID:27772 發(fā)表于 2011-1-15 16:51 | 顯示全部樓層
謝謝你,我發(fā)現(xiàn)是數(shù)據(jù)類型錯了,直接寫int的,1602會當(dāng)做指令處理了,增加了一個switch語句,把原始數(shù)據(jù)轉(zhuǎn)換成一位一位的,顯示出來 就ok了,不過發(fā)現(xiàn)這款單片機(jī)AD轉(zhuǎn)換線性不夠好,誤差比較大
回復(fù)

使用道具 舉報

ID:27770 發(fā)表于 2011-1-16 14:29 | 顯示全部樓層

祝賀你的成功!----畢竟,論壇的幫助很有限,主要還是靠你自己的努力!

STC12C5A60S2  ----包括許多牌子的單片機(jī)自帶的 AD 效果都不怎么好,如果你希望依靠它作出比較好的效果來,是要付出比較大的努力的!

把你的測量范圍分割為 100 份,甚至 1000 份.每一份單獨測量出來,取16次平均值,作為標(biāo)準(zhǔn).制定一個表格,然后,把 AD 讀數(shù)通過查表去得到實際電壓數(shù)據(jù).---表格越多越是精確,越是辛苦!

要不要試一下?

僅供參考!

回復(fù)

使用道具 舉報

ID:80407 發(fā)表于 2015-6-8 07:22 | 顯示全部樓層
樓主,你好!我的ADC0809的數(shù)據(jù)輸入口和液晶屏的數(shù)據(jù)口都用的P0口但是ADC0809加了一個鎖存器,但是還是出現(xiàn)亂碼的情況,請問這樣怎么辦?
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表