单片机 【AD/DA模块】



1 #include <reg52.h> 2 #include <intrins.h> 3 #define MAIN_Fosc 11059200UL //宏定义主时钟HZ 4 #define PCF8591_ADDR 0x90 //PCF8591地址 5 #define DACOUT_EN 0x40 //DAC输出使能 6 7 /*==================================== 8 自定义类型名 9 ====================================*/ 10 typedef unsigned char INT8U; 11 typedef unsigned char uchar; 12 13 typedef unsigned int INT16U; 14 typedef unsigned int uint; 15 16 /*==================================== 17 硬件接口位声明 18 ====================================*/ 19 sbit SDA = P2^0; //I2C串行数据 20 sbit SCL = P2^1; //I2C串行时钟 21 sbit DU = P2^6; //数码管段选 22 sbit WE = P2^7; //数码管位选 23 sbit LED1= P1^0; //读取AD的值是否成功(亮成功,灭失败) 24 sbit LED2= P1^1; //DAC成功输出(亮成功,灭失败) 25 sbit BEEP= P2^3; //蜂鸣器引脚定义 26 27 uchar AD_Value; //存储AD转换回的数字量 28 /*==================================== 29 共阴极数码管段选码 30 ====================================*/ 31 uchar code table[]={ 32 //0 1 2 3 4 5 6 7 8 33 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 34 //9 A B C D E F - . 关显示 35 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00 36 }; 37 38 /*==================================== 39 数码管位选码 40 ====================================*/ 41 //第1位 2位 3位 4位 5位 6位 7位 8位 42 uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码 43 44 /*==================================== 45 函数:void Delay_Ms(INT16U ms) 46 参数:ms,毫秒延时形参 47 描述:12T 51单片机自适应主时钟毫秒级延时函数 48 ====================================*/ 49 void Delay_Ms(INT16U ms) 50 { 51 INT16U i; 52 do{ 53 i = MAIN_Fosc / 96000; 54 while(--i); //96T per loop 55 }while(--ms); 56 } 57 58 /*==================================== 59 函数:void Delay5us() 60 描述:12T 51单片机5微秒延时函数自适应时钟(11.0592M,12M,22.1184M) 61 ====================================*/ 62 void Delay5us() 63 { 64 #if MAIN_Fosc == 11059200 65 _nop_(); 66 #elif MAIN_Fosc == 12000000 67 _nop_(); 68 #elif MAIN_Fosc == 22118400 69 _nop_(); _nop_(); _nop_(); 70 #endif 71 } 72 73 /*==================================== 74 函数:void Display(INT8U Value) 75 参数:Value,显示值 取值0-255 76 描述:共阴极数码管显示函数可显示一个字节的数 77 ====================================*/ 78 void Display(INT8U Value) 79 { 80 //------------------------------ 81 DU = 1; 82 P0 = table[Value/100]; //管显示百位 83 DU = 0; 84 85 P0 = 0xff; //清除断码 86 87 WE = 1; 88 P0 = T_COM[0]; //第一位数码管 89 WE = 0; 90 Delay_Ms(5); 91 //------------------------------- 92 DU = 1; 93 P0 = table[Value%100/10]; //显示十位 94 DU = 0; 95 96 P0 = 0xff; //清除断码 97 98 WE = 1; 99 P0 = T_COM[1]; //第二位数码管 100 WE = 0; 101 Delay_Ms(5); 102 //------------------------------- 103 DU = 1; 104 P0 = table[Value%10]; //显示个位 105 DU = 0; 106 107 P0 = 0xff; //清除断码 108 109 WE = 1; 110 P0 = T_COM[2]; //第三位数码管 111 WE = 0; 112 Delay_Ms(5); 113 } 114 115 /*==================================== 116 函数:I2C_init() 117 描述:I2C总线初始化 118 ====================================*/ 119 void I2C_init() 120 { 121 SDA = 1; //数据总线高 122 _nop_(); 123 SCL = 1; //时钟总线高 124 _nop_(); 125 } 126 127 /*==================================== 128 函数:I2C_Start() 129 描述:I2C起始信号 130 ====================================*/ 131 void I2C_Start() 132 { 133 SCL = 1; 134 _nop_(); 135 SDA = 1; 136 Delay5us(); 137 SDA = 0; 138 Delay5us(); 139 } 140 141 /*==================================== 142 函数:I2C_Stop() 143 描述:I2C停止信号 144 ====================================*/ 145 void I2C_Stop() 146 { 147 SDA = 0; 148 _nop_(); 149 SCL = 1; 150 Delay5us(); 151 SDA = 1; 152 Delay5us(); 153 } 154 155 /*==================================== 156 函数:Master_ACK(bit i) 157 参数:i 为0时发送非应答 为1时发送应答 158 描述:I2C主机发送应答 159 ====================================*/ 160 void Master_ACK(bit i) 161 { 162 SCL = 0; // 拉低时钟总线允许SDA数据总线上的数据变化 163 _nop_(); // 让总线稳定 164 if (i) //如果i = 1 那么拉低数据总线 表示主机应答 165 { 166 SDA = 0; 167 } 168 else 169 { 170 SDA = 1; //发送非应答 171 } 172 _nop_();//让总线稳定 173 SCL = 1;//拉高时钟总线 让从机从SDA线上读走 主机的应答信号 174 _nop_(); 175 SCL = 0;//拉低时钟总线, 占用总线继续通信 176 _nop_(); 177 SDA = 1;//释放SDA数据总线。 178 _nop_(); 179 } 180 181 /*==================================== 182 函数:Test_ACK() 183 返回:0为非应答 1为应答 184 描述:I2C检测从机应答 185 ====================================*/ 186 bit Test_ACK() // 检测从机应答 187 { 188 SCL = 1;//时钟总线为高电平期间可以读取从机应答信号 189 Delay5us(); 190 if (SDA) 191 { 192 SCL = 0; 193 I2C_Stop(); 194 return(0); 195 } 196 else 197 { 198 SCL = 0; 199 return(1); 200 } 201 } 202 203 /*==================================== 204 函数:I2C_send_byte(uchar byte) 205 参数:byte 要发送的字节 206 描述:I2C发送一个字节 207 ====================================*/ 208 void I2C_send_byte(uchar byte) 209 { 210 uchar i; 211 for(i = 0 ; i < 8 ; i++) 212 { 213 SCL = 0; 214 _nop_(); 215 if (byte & 0x80) // 216 { 217 SDA = 1; 218 _nop_(); 219 } 220 else 221 { 222 SDA = 0; 223 _nop_(); 224 } 225 SCL = 1; 226 _nop_(); 227 byte <<= 1; 228 } 229 SCL = 0; 230 _nop_(); 231 SDA = 1; 232 _nop_(); 233 } 234 235 /*==================================== 236 函数:I2C_read_byte() 237 返回:读取的字节 238 描述:I2C读一个字节 239 ====================================*/ 240 uchar I2C_read_byte() 241 { 242 uchar i, dat; 243 SCL = 0 ; 244 _nop_(); 245 SDA = 1; 246 _nop_(); 247 for(i = 0 ; i < 8 ; i++) 248 { 249 SCL = 1; 250 _nop_(); 251 dat <<= 1; 252 if (SDA) 253 { 254 dat |= 0x01; 255 } 256 _nop_(); 257 SCL = 0; 258 _nop_(); 259 } 260 return(dat); 261 } 262 263 /*DAC输出*/ 264 bit DAC_OUT(uchar DAT) 265 { 266 I2C_Start(); 267 I2C_send_byte(PCF8591_ADDR+0);// 268 if (!Test_ACK()) 269 { 270 return(0); 271 } 272 I2C_send_byte(DACOUT_EN);// //DA输出使能 273 if (!Test_ACK()) 274 { 275 return(0); 276 } 277 I2C_send_byte(DAT); 278 if (!Test_ACK()) 279 { 280 return(0); 281 } 282 I2C_Stop(); 283 return(1); 284 } 285 286 /*读AD数据*/ 287 bit ADC_Read(uchar CON) 288 { 289 I2C_Start(); 290 I2C_send_byte(PCF8591_ADDR+0); 291 if (!Test_ACK()) 292 { 293 return(0); 294 } 295 I2C_send_byte(CON); // 296 Master_ACK(0); 297 I2C_Start(); 298 I2C_send_byte(PCF8591_ADDR+1); 299 if (!Test_ACK()) 300 { 301 return(0); 302 } 303 AD_Value = I2C_read_byte(); 304 Master_ACK(0); 305 I2C_Stop(); 306 return(1); 307 } 308 309 void main() 310 { 311 I2C_init(); 312 while(1) 313 { 314 //单端输入,读出通道2的值 315 if (ADC_Read(0x02)) LED1 = 0; else LED1 = 1; 316 if (DAC_OUT(AD_Value)) LED2 = 0; else LED2 = 1; 317 Display(AD_Value); 318 if (AD_Value > 150) BEEP = 0; else BEEP = 1; 319 Delay_Ms(5); 320 } 321 }
一个二次元的生物

浙公网安备 33010602011771号