-
Notifications
You must be signed in to change notification settings - Fork 1
/
GenerateSin.c
140 lines (122 loc) · 4.27 KB
/
GenerateSin.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//Sine Wave generator code for F38x board
//Converts square wave signal to sine wave signal; modify the modifier value to change frequency
//Uses 3 10k resistors and 3 100nf caps and works in the 75-150Hz range
//
//Code adapted by Jake Osborne from Dr. Calvino-Fraga's base timer code 2017
#include <C8051F38x.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define SYSCLK 48000000L // SYSCLK frequency in Hz
#define BAUDRATE 115200L // Baud rate of UART in bps
#define SINEPIN P2_5
#define SINEPIN2 P2_1
volatile unsigned int sine=0;
volatile unsigned int modifier=1;
char _c51_external_startup (void)
{
PCA0MD&=(~0x40) ; // DISABLE WDT: clear Watchdog Enable bit
VDM0CN=0x80; // enable VDD monitor
RSTSRC=0x02|0x04; // Enable reset on missing clock detector and VDD
// CLKSEL&=0b_1111_1000; // Not needed because CLKSEL==0 after reset
#if (SYSCLK == 12000000L)
//CLKSEL|=0b_0000_0000; // SYSCLK derived from the Internal High-Frequency Oscillator / 4
#elif (SYSCLK == 24000000L)
CLKSEL|=0b_0000_0010; // SYSCLK derived from the Internal High-Frequency Oscillator / 2.
#elif (SYSCLK == 48000000L)
CLKSEL|=0b_0000_0011; // SYSCLK derived from the Internal High-Frequency Oscillator / 1.
#else
#error SYSCLK must be either 12000000L, 24000000L, or 48000000L
#endif
OSCICN |= 0x03; // Configure internal oscillator for its maximum frequency
// Configure UART0
SCON0 = 0x10;
#if (SYSCLK/BAUDRATE/2L/256L < 1)
TH1 = 0x10000-((SYSCLK/BAUDRATE)/2L);
CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
CKCON |= 0x08;
#elif (SYSCLK/BAUDRATE/2L/256L < 4)
TH1 = 0x10000-(SYSCLK/BAUDRATE/2L/4L);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x01;
#elif (SYSCLK/BAUDRATE/2L/256L < 12)
TH1 = 0x10000-(SYSCLK/BAUDRATE/2L/12L);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
#else
TH1 = 0x10000-(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
#endif
TL1 = TH1; // Init Timer1
TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI = 1; // Indicate TX0 ready
// Configure the pins used for square output
P2MDOUT|=0b_0000_0011;
P0MDOUT |= 0x10; // Enable UTX as push-pull output
XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
XBR1 = 0x40; // Enable crossbar and weak pull-ups
return 0;
}
void Timer2_Init (void)
{
// Initialize timer 2 for periodic interrupts
TMR2CN=0x00; // Stop Timer2; Clear TF2;
CKCON|=0b_0001_0000;
TMR2RL=(-(SYSCLK/((2*48)+modifier))/(100L)); // Initialize reload value
TMR2=0xffff; // Set to reload immediately
ET2=1; // Enable Timer2 interrupts
TR2=1; // Start Timer2
EA=1; // Enable interrupts
}
void Timer2_ISR (void) interrupt 5 using 1
{
static unsigned char pwm_count;
TF2H = 0; // Clear Timer2 interrupt flag
pwm_count++;
if(pwm_count>100) pwm_count=0;
SINEPIN=pwm_count>sine?0:1;
SINEPIN2=pwm_count>sine?0:1;
}
// Uses Timer3 to delay <us> micro-seconds.
void Timer3us(unsigned char us)
{
unsigned char i; // usec counter
// The input for Timer 3 is selected as SYSCLK by setting T3ML (bit 6) of CKCON:
CKCON|=0b_0100_0000;
TMR3RL = (-(SYSCLK)/1000000L); // Set Timer3 to overflow in 1us.
TMR3 = TMR3RL; // Initialize Timer3 for first overflow
TMR3CN = 0x04; // Sart Timer3 and clear overflow flag
for (i = 0; i < us; i++) // Count <us> overflows
{
while (!(TMR3CN & 0x80)); // Wait for overflow
TMR3CN &= ~(0x80); // Clear overflow indicator
}
TMR3CN = 0 ; // Stop Timer3 and clear overflow flag
}
void waitms (unsigned int ms)
{
unsigned int j;
unsigned char k;
for(j=0; j<ms; j++)
for (k=0; k<4; k++) Timer3us(250);
}
void main (void)
{
signed int scannedValue;
printf("\x1b[2J"); // Clear screen using ANSI escape sequence.
sine = 50;
Timer2_Init();
while(1)
{
printf("Enter Modifier 1: \r\n");
scanf("%i",&scannedValue);
printf("Entered %i\n\r",scannedValue);
modifier = scannedValue;
ET2=0; // Enable Timer2 interrupts
TR2=0; // Start Timer2
EA=0; // Enable interrupts
Timer2_Init();
}
}