代码拉取完成,页面将自动刷新
C51 COMPILER V9.01 MAIN 07/13/2018 14:44:08 PAGE 1
C51 COMPILER V9.01, COMPILATION OF MODULE MAIN
OBJECT MODULE PLACED IN main.obj
COMPILER INVOKED BY: G:\Keil\k4\C51\BIN\C51.EXE src\main.c BROWSE DEBUG OBJECTEXTEND PRINT(.\main.lst) OBJECT(main.obj)
line level source
1 /**********************************************************************
2 @Author: frank.xin
3 @Date : 7/11/2018
4 File name : main.c
5 File target: STC89C52 with PCF8591 ADDA Converter
6 Approach : To generate a series of waves including sin(SIN),
7 triangle(TRI), sawtooth(SAW), square(SQR) whose amplitude and their
8 frequency can be adjusted by pressing keys. Details can be found at
9 http://frank.xin
10 **********************************************************************/
11 #include <reg52.h>
12 #include <intrins.h>
13 #include "timer.h"
14 #include "key.h"
15 #include "pcf8591.h"
16
17 // size of wave form array
18 // also used in calculating waves
19 #define WAVE_SIZE 32
20 // maximum voltage output
21 #define MAX_VOLT ((float)5.0)
22 // default timer reloading value
23 #define DEFAULT_TL (65536-251)%256
24 #define DEFAULT_TH (65536-251)/256
25 // step when changing frequency, R for Rough, A for Accurate
26 // (Tested) Rough changes about 20Hz a time
27 // Accurate changes about 1Hz a time
28 // THE FREQUENCY CHANGING IS NON-LINEAR BUT
29 // THERE IS NO SOLUTION PROVIDED IN THIS ALGORITHM
30 #define FREQUENCY_STEP_R 28
31 #define FREQUENCY_STEP_A 7
32
33 // Generate sin waveForm
34 void genSin();
35 // Generate Triangle waveForm
36 void genTri();
37 // Generate Sawtooth waveForm
38 void genSaw();
39 // Generate Square waveForm
40 void genSqr();
41
42 // index of indexing waveForm
43 unsigned char index;
44 // used in for loops
45 unsigned char i;
46 bit hasStart;
47 // storing keycode
48 unsigned char keyCode;
49 // initValue of Timer
50 unsigned int initValue;
51 // reloading value of TH and TL
52 unsigned int tlValue, thValue;
53 // output voltage, modified by key pressing
54 float voltage;
55 // function pointer, point to genWaves(), for brief calling
C51 COMPILER V9.01 MAIN 07/13/2018 14:44:08 PAGE 2
56 void (*generater)(void);
57
58 // Table of sin wave
59 unsigned char sin[] = {
60 // Uncomment this line below when WAVE_SIZE==16
61 // 128,176,218,245,255,245,218,176,128,79,37,10,0,10,37,79
62 // Comment the lines below when WAVE_SIZE==16
63 128, 152, 176, 198, 218, 234, 245, 253,
64 255, 253, 245, 234, 218, 198, 176, 152,
65 128, 103, 79, 57, 37, 21, 10, 2,
66 0, 2, 10, 21, 37, 57, 79, 103
67 };
68 // Table of LUT, recalculated whenever a loop in main()
69 volatile unsigned char waveForm[WAVE_SIZE];
70
71 /*
72 * Initialization
73 * This function is for global usage
74 * Initialize these things:
75 * Timer0, DA, P1(for showing status of program)
76 * voltage, initValue(used in Timer0, for reloaing values)
77 * tlValue & thValue (calculated initValue, for reloading values in Timer 0)
78 * generater (function pointer, for calculating waveForm[])
79 */
80 void init() {
81 1 P1 = 0xfe; // Light on LED 0
82 1 voltage = 5.0; // Maximum initial voltage output
83 1 hasStart = 1;
84 1 initValue = 251; // (Tested) Under this value, the frequency is 100Hz
85 1 tlValue = (65536-initValue)%256; // Reloading value of Timer
86 1 thValue = (65536-initValue)/256; // Reloading value of Timer
87 1 generater = genSin; // Function pointer pointing to genSin()
88 1 generater(); // Call function pointer (genSin() here)
89 1 DACStart(); // Send the ADDRESS and CONTROL bytes to PCF8591
90 1 Init_Timer0(); // Enable Interrupt
91 1 }
92 // main entrance
93 void main() {
94 1 init(); // Initialize things
95 1 // main loop
96 1 while(1) {
97 2 keyCode = mKeyScan(); // Get key press info
98 2 switch(keyCode) {
99 3 case KEY_NULL: // No key pressed (or invalied key)
100 3 break;
101 3 case KEY_ONOFF: // Display controlling (not used)
102 3 hasStart = !hasStart;
103 3 break;
104 3 case KEY_SIN: // Switch to sin wave
105 3 generater = genSin; // Function pointer, ready to call
106 3 break;
107 3 case KEY_SQR: // Switch to square wave
108 3 generater = genSqr;
109 3 break;
110 3 case KEY_SAW: // Switch to sawtooth wave
111 3 generater = genSaw;
112 3 break;
113 3 case KEY_TRI: // Switch to triangle wave
114 3 generater = genTri;
115 3 break;
116 3 case KEY_FRE_R_ADD: // Rough add frequency
117 3 initValue -= FREQUENCY_STEP_R; // that is, sub of delay
C51 COMPILER V9.01 MAIN 07/13/2018 14:44:08 PAGE 3
118 3 break;
119 3 case KEY_FRE_R_SUB: // Rough sub frequency
120 3 initValue += FREQUENCY_STEP_R;
121 3 break;
122 3 case KEY_FRE_A_ADD: // Accurate add frequency
123 3 initValue -= FREQUENCY_STEP_A;
124 3 break;
125 3 case KEY_FRE_A_SUB:
126 3 initValue += FREQUENCY_STEP_A;
127 3 break;
128 3 case KEY_AMP_R_ADD: // Rough add amplitude (output voltage)
129 3 voltage += 0.1;
130 3 break;
131 3 case KEY_AMP_R_SUB:
132 3 voltage -= 0.1;
133 3 break;
134 3 case KEY_AMP_A_ADD:
135 3 voltage += 0.01;
136 3 break;
137 3 case KEY_AMP_A_SUB:
138 3 voltage -= 0.01;
139 3 break;
140 3 default:
141 3 break;
142 3 }
143 2 if(voltage < 0) { // Voltage range: 0~5V
144 3 voltage = 0.1;
145 3 }
146 2 if(voltage > 5.0) {
147 3 voltage = 5.0;
148 3 }
149 2 if(initValue < 251) { // Timer should be no faster than this
150 3 initValue = 251; // or DAC would not run normally
151 3 }
152 2 if(initValue > 65534) { // 65535 is the maximum value of timer
153 3 initValue = 65534;
154 3 }
155 2 tlValue = (65536-initValue)%256; // Recalculate timer reloading values
156 2 thValue = (65536-initValue)/256;
157 2
158 2 generater(); // Regenerate wave form (calculates even if nothing changes)
159 2 }
160 1 }
161
162 void onTimer0() interrupt 1 {
163 1 TL0 = tlValue; // Reload timer values
164 1 TH0 = thValue; // Reload timer values
165 1 if (hasStart) {
166 2 index ++; // Increase index, indexing next element in waveForm[]
167 2 if(index == WAVE_SIZE) { // Array out range
168 3 index = 0;
169 3 }
170 2 /*
171 2 * Send next data into DAC
172 2 * Connection already set up by calling DACStart()
173 2 * According to documentation, there can be unlimited
174 2 * data sent to DAC
175 2 */
176 2 ContinuesSend(waveForm[index]);
177 2 }
178 1 }
179
C51 COMPILER V9.01 MAIN 07/13/2018 14:44:08 PAGE 4
180 /*
181 * Generating sawtooth wave
182 * Sawtooth wave increases in all-along period from zero
183 * For a maximum voltage(MAX_VOLT) and a 32-element array,
184 * increase 256/32=8 each time
185 * Result should multi (voltage/MAX_VOLT) for voltage-adjusting
186 */
187 void genSaw() { // 32
188 1 for(i = 0; i < WAVE_SIZE; i++) {
189 2 waveForm[i] = i*(255/WAVE_SIZE)*(voltage/MAX_VOLT);
190 2 }
191 1 }
192
193 /*
194 * Sin wave calculating takes a lot of time so here
195 * use a preset table to index sin wave forms
196 * Only need to multi voltage adjusting value
197 */
198 void genSin() {
199 1 for(i = 0; i < WAVE_SIZE; i++) {
200 2 waveForm[i] = sin[i]*(voltage/MAX_VOLT);
201 2 }
202 1 }
203
204 /*
205 * Square waves are quite simple to calculate
206 * During the first half period, the output is maximum value
207 * and on the last half period it is zero (zero ignoring voltage adjusting)
208 */
209 void genSqr() {
210 1 for(i = 0; i < WAVE_SIZE/2; i++) {
211 2 waveForm[i] = (255)*(voltage/MAX_VOLT);
212 2 }
213 1 for(i = WAVE_SIZE/2; i < WAVE_SIZE; i++) {
214 2 waveForm[i] = 0;
215 2 }
216 1 }
217
218 /*
219 * Triangle waves increase in the first half period and decrease in the last
220 * half period. (Tested) There is a half-WAVE_SIZE offset in the first value,
221 * so use algo to compensate the offset, that is how the WAVE_SIZE/2 + comes.
222 */
223 void genTri() {
224 1 for(i = 0; i < WAVE_SIZE/2; i++) {
225 2 waveForm[i] = (WAVE_SIZE/2 + i*(255/WAVE_SIZE*2))*(voltage/MAX_VOLT);
226 2 }
227 1 for(i = WAVE_SIZE/2; i < WAVE_SIZE; i++) {
228 2 waveForm[i] = 255*(voltage/MAX_VOLT) - waveForm[i - WAVE_SIZE/2];
229 2 }
230 1 }
231
232
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1017 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 80 ----
IDATA SIZE = ---- ----
C51 COMPILER V9.01 MAIN 07/13/2018 14:44:08 PAGE 5
BIT SIZE = 1 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。