% Create A SineTable for PIC DDS % ************************************************** % % (C) Copyright notice % % Written by Richard Prinz. % Copyright 2003 by Richard Prinz. % OE1RIB Richard.Prinz@MIN.at % % Permission to use, copy, and modify this program % without restriction is hereby granted, as long as % % 1) this copyright notice appears in each copy of % the program source code and % % 2) the source code is not used for commercial % purposes. % % This program is freely distributable without % licensing fees and is provided without guarantee % or warrantee expressed or implied. % % This program is -not- in the public domain. % % ************************************************** % ----- USER CONFIG ----- TableSize = 256; % number of elements in sinetable Floop = 28; % number of instructions per DDS loop Freq = 1000; % wanted output Frequency AccWidth = 3; % accumulator width 3 Bytes fXtal = 4000000; % main PIC16F84 oscilliator Frequency in Hz % ----- DON'T CHANGE ANYTHING AFTER HERE ----- format long disp('***********************************************************************************'); c = 360 / TableSize; i = 0 : TableSize - 1; d = c * i; e = d * pi / 180; f = sin(e); g = f * fix((TableSize / 2) - 1); fSineTable = fix(TableSize / 2) + g; %iSineTable = fix(fSineTable); iSineTable = round(fSineTable); % Plot SineTable if 1 == 1 figure(1); clf; plot(fSineTable, '-ro'); hold on; plot(iSineTable, '-b*'); title(sprintf('SineTable using %d Elements', TableSize)); xlabel(sprintf('(comparison between Int and Float Table entries)\nZoom to show details')); legend('Float','Int',-1); end % fill iSineTable to next 8 digit boundary and reshape baseSineTable = cat(2, iSineTable, zeros(1, abs( size(iSineTable, 2) - fix( (size(iSineTable, 2) + 7) / 8) * 8))); % create decimal table for copying into source disp(sprintf('Decimal Sine Table using %d Elements', TableSize)); disp(' '); decSineTable = reshape(baseSineTable, 8, size(baseSineTable, 2) / 8); decSineTable = rot90(decSineTable); decSineTable = flipud(decSineTable); disp(decSineTable) % create hex table for copying into source disp(sprintf('\nHexadecimal Sine Table using %d Elements', TableSize)); disp(' '); hexSineTable = cellstr( strcat('0x',dec2base(baseSineTable, 16, 2))); hexSineTable = reshape(hexSineTable, 8, size(hexSineTable, 1) / 8); hexSineTable = rot90(hexSineTable); hexSineTable = flipud(hexSineTable); %disp(hexSineTable) for i=1:size(hexSineTable,1) disp(sprintf('dt\t\t\t\t%s,%s,%s,%s,%s,%s,%s,%s',char(hexSineTable(i,1)), char(hexSineTable(i,2)), char(hexSineTable(i,3)), char(hexSineTable(i,4)), char(hexSineTable(i,5)), char(hexSineTable(i,6)), char(hexSineTable(i,7)), char(hexSineTable(i,8)))); end disp('***********************************************************************************'); finst = fXtal / 4; % pic instructions per second faccmax = 2^(AccWidth * 8); ftest = fix(finst / Freq); % pic instructions possible per 1 period fconst = (finst / Floop) / faccmax; fstep = fix(Freq / fconst) facc = 0; fsamples = 0; lastacc = 0; fsineout = zeros(1, ftest); ftriangle = zeros(1, ftest); for i = 1:Floop:ftest facc = facc + fstep; facchighbyte = mod(fix(facc / 2^((AccWidth - 1) * 8)), TableSize); fsineout(1, i:i + Floop) = iSineTable(facchighbyte + 1); ftriangle(1, i:i + Floop) = facchighbyte + 1; if lastacc ~= facchighbyte fsamples = fsamples + 1; end lastacc = facchighbyte; end figure(2); clf; %plot(fres,'-rs','MarkerSize',2); plot(fsineout,'-r'); hold on; plot(ftriangle,'--b'); grid on; title(sprintf('PicDDS Sine Plot (%d Hz)', Freq)); ylabel('SineTable Value'); xlabel(sprintf('1 Period allows %d PIC Instructions =\n%.6f seconds = %d SineTab Samples = %d Cycles/Sample', ftest, (1/finst)*ftest, fsamples, Floop)); legend('Sine','SawTooth',1); %fres