2016年11月16日 星期三

FlatCam 使用心得

2016-11-16 使用FlatCam 来切割外框。

今天需要切割底板的外形。

试用了Cam350,功能强大,适合做底板厂的公司的样子,不会用,用Cam350产生的外框切割的Code,不是G-Code,无法给Mach3 CNC使用。放弃。

试用了LazyCam,Mach3 自带的,感觉按键后都没啥反应的样子,不太会用。放弃。

Altium 也可以直接对PCB产生G-Code,可是好像没有对应的Script. 研究了下放弃。

最后想起下载过FlatCam,研究了一下,感觉挺厉害的。
先在Altium 输出一个Gerber的外框图。 如果是单纯线的外框,用走线的功能,会在线的两边,挖槽,这样不是我要的。
FlatCam的外框CutOut功能只能是正方形吗?这也不是我要的。
最后,回到Altium把Keepout全部填满,再输出G-Code。再导入FlatCam。

1. 在FlatCam,第一步, 双击Gerber,在Selected页面,输入工具参数,然后Generate Geometry.
2. 双击产生的ISO(lated)文件,在Selected页面,输入板厚,板进等参数,然后Generate
3. 在产生的 ISO_CNC文件下,就可以Export G-Code。
4. 这个G-Code 可以在Mach3的CNC下面使用。

这里面预设使用 inch单位,日后需要再研究如何用mm单位。

这工具很好用,怕日后忘记,在这里做下记录。




2012年12月29日 星期六

C Pointer Vs Pascal Pointer
大家都認為,C語言之所以強大,以及其自由性,很大部分體現在其靈活的POINTER運用上。因此,說POINTER是C語言的靈魂,一點都不為過。同時,這種說法也讓很多人產生誤解,似乎只有C語言的POINTER才能算POINTER。Basic不支持POINTER,在此不論。其實,Pascal語言本身也是支持POINTER的。從最初的Pascal發展至今的Object Pascal,可以說在POINTER運用上,絲毫不會遜色於C語言的POINTER。

以下內容分為八個部分,分別是
一、類型POINTER的定義
二、無類型POINTER的定義
三、POINTER的解除引用
四、取地址(POINTER賦值)
五、POINTER運算
六、動態記憶體分配
七、字元陣列的運算
八、函數POINTER


一、類型POINTER的定義。對於指向特定類型的POINTER,在C中是這樣定義的:
int *ptr;
char *ptr;
與之等價的Object Pascal是如何定義的呢?
var
ptr : ^Integer;
ptr : ^char;
其實也就是符號的差別而已。

二、無類型POINTER的定義。C中有void *類型,也就是可以指向任何類型數據的POINTER。Object Pascal為其定義了一個專門的類型:Pointer。於是,
ptr : Pointer;
就與C中的
void *ptr;
等價了。

三、POINTER的解除引用。要解除POINTER引用(即取出POINTER所指區域的值),C 的語法是 (*ptr),Object Pascal則是 ptr^。

四、取地址(POINTER賦值)。取某對象的地址並將其賦值給POINTER變量,C 的語法是
ptr = &Object;
Object Pascal 則是
ptr := @Object;
也只是符號的差別而已。

五、POINTER運算。在C中,可以對POINTER進行移動的運算,如:
char a[20]; 
char *ptr=a; 
ptr++;
ptr+=2;
當執行ptr++;時,編譯器會產生讓ptr前進sizeof(char)步長的程式碼,之後,ptr將指向a[1]。ptr+=2;這句使得ptr前進兩個sizeof(char)大小的步長。同樣,我們來看一下Object Pascal中如何實現:
var
a : array [1..20] of Char;
ptr : PChar; //PChar 可以看作 ^Char
begin
ptr := @a;
Inc(ptr); // 這句等價於 C 的 ptr++;
Inc(ptr, 2); //這句等價於 C 的 ptr+=2;
end;

六、動態記憶體分配。C中,使用malloc()庫函數分配記憶體,free()函數釋放記憶體。如這樣的程式碼:
int *ptr, *ptr2;
int i;
ptr = (int*) malloc(sizeof(int) * 20);
ptr2 = ptr;
for (i=0; i<20; i++){
*ptr = i;
ptr++;
}
free(ptr2);
Object Pascal中,動態分配記憶體的函數是GetMem(),與之對應的釋放函數為FreeMem()(傳統Pascal中獲取記憶體的函數是New()和 Dispose(),但New()只能獲得對象的單個實體的記憶體大小,無法取得連續的存放多個對象的記憶體塊)。因此,與上面那段C的程式碼等價的 Object Pascal的程式碼為:
var ptr, ptr2 : ^integer;
i : integer;
begin
GetMem(ptr, sizeof(integer) * 20);
//這句等價於C的 ptr = (int*) malloc(sizeof(int) * 20);
ptr2 := ptr; //保留原始POINTER位置
for i := 0 to 19 do
begin
ptr^ := i;
Inc(ptr);
end;
FreeMem(ptr2);
end;
對於以上這個例子(無論是C版本的,還是Object Pascal版本的),都要注意一個問題,就是分配記憶體的單位是位元組(BYTE),因此在使用GetMem時,其第二個參數如果想當然的寫成 20,那麼就會出問題了(記憶體存取越界)。因為GetMem(ptr, 20);實際只分配了20個位元組的記憶體空間,而一個整形的大小是四個位元組,那麼存取第五個之後的所有元素都是非法的了(對於malloc()的參數同樣)。

七、字元陣列的運算。C語言中,是沒有字元串類型的,因此,字元串都是用字元陣列來實現,於是也有一套str打頭的庫函數以進行字元陣列的運算,如以下程式碼:
char str[15];
char *pstr;
strcpy(str, "teststr");
strcat(str, "_testok");
pstr = (char*) malloc(sizeof(char) * 15);
strcpy(pstr, str);
printf(pstr);
free(pstr);
而在Object Pascal中,有了String類型,因此可以很方便的對字元串進行各種運算。但是,有時我們的Pascal程式碼需要與C的程式碼交互(比如:用 Object Pascal的程式碼調用C寫的DLL或者用Object Pascal寫的DLL准備允許用C寫客戶端的程式碼)的話,就不能使用String類型了,而必須使用兩種語言通用的字元陣列。其實,Object Pascal提供了完全相似C的一整套字元陣列的運算函數,以上那段程式碼的Object Pascal版本是這樣的:
var str : array [1..15] of char;
pstr : PChar; //Pchar 也就是 ^Char
begin
StrCopy(@str, 'teststr'); //在C中,陣列的名稱可以直接作為陣列首地址POINTER來用
//但Pascal不是這樣的,因此 str前要加上取地址的運算符
StrCat(@str, '_testok');
GetMem(pstr, sizeof(char) * 15);
StrCopy(pstr, @str);
Write(pstr);
FreeMem(pstr);
end;

八、函數POINTER。在動態調用DLL中的函數時,就會用到函數POINTER。假設用C寫的一段程式碼如下:
typedef int (*PVFN)(int); //定義函數POINTER類型
int main()
{
HMODULE hModule = LoadLibrary("test.dll");
PVFN pvfn = NULL;
pvfn = (PVFN) GetProcAddress(hModule, "Function1");
pvfn(2);
FreeLibrary(hModule);
}
就我個人感覺來說,C語言中定義函數POINTER類型的typedef程式碼的語法有些不明,而同樣的程式碼在Object Pascal中卻非常易懂:
type PVFN = Function (para : Integer) : Integer;
var
fn : PVFN;
//也可以直接在此處定義,如:fn : function (para:Integer):Integer;
hm : HMODULE;
begin
hm := LoadLibrary('test.dll');
fn := GetProcAddress(hm, 'Function1');
fn(2);
FreeLibrary(hm);
end;

2012年10月25日 星期四

Delphi控制Excel(一)


delphi控制Excel(一)

內容來源:雨轩客的博客网_你的博客网

use ComObj,Excel97

首先创建 Excel 对象,使用ComObj:
var ExcelID: Variant;

ExcelID := CreateOleObject( ’Excel.Application’ );

1) 显示当前窗口:ExcelID.Visible := True;

2) 更改 Excel 标题栏: ExcelID.Caption := ’应用程序调用 Microsoft Excel’;

3) 添加新工作簿: ExcelID.WorkBooks.Add;
MsExcel.WorkBooks.Add(xlWBatWorkSheet);//增加一個WorkBook並且有一個Sheet
MSExcel.WorkBooks[1].Sheets.Add(,,17,xlWorkSheet)//在此WorkBook內在增加17個Sheet
Sheets :=XLApp.WorkBooks[1].Sheets;//指定Sheets為第一個WorkBook內的 SheetsSheets.Item[1].Name :='該Sheet的名稱';//指定此Sheets內的第一個Sheet名稱

4) 打开已存在的工作簿: ExcelID.WorkBooks.Open( ’C:\Excel\Demo.xls’ );

5) 设置第2个工作表为活动工作表: ExcelID.WorkSheets[2].Activate;
或 ExcelID.WorksSheets[ ’Sheet2’ ].Activate;

6) 给单元格赋值: ExcelID.Cells[1,4].value := ’第一行第四列’;

7) 设置指定列的宽度(单位:字符个数),以第一列为例: ExcelID.ActiveSheet.Column[1].ColumnsWidth := 5;

8) 设置指定行的高度(单位:磅)(1磅=0.035厘米),以第二行为例: ExcelID.ActiveSheet.Rows[2].RowHeight := 1/0.035; // 1厘米

9) 在第8行之前插入分页符: ExcelID.WorkSheets[1].Rows.PageBreak := 1;

10) 在第8列之前删除分页符: ExcelID.ActiveSheet.Columns[4].PageBreak := 0;

11) 指定边框线宽度: ExcelID.ActiveSheet.Range[ ’B3:D4’ ].Borders[2].Weight := 3;
1-左 2-右 3-顶 4-底 5-斜( \ ) 6-斜( / )

12) 清除第一行第四列单元格公式: ExcelID.ActiveSheet.Cells[1,4].ClearContents;

13) 设置第一行字体属性:
ExcelID.ActiveSheet.Rows[1].Font.Name := ’隶书’;
ExcelID.ActiveSheet.Rows[1].Font.Color := clBlue;
ExcelID.ActiveSheet.Rows[1].Font.Bold := True;
ExcelID.ActiveSheet.Rows[1].Font.UnderLine := True;

14) 进行页面设置:
a.页眉: ExcelID.ActiveSheet.PageSetup.CenterHeader := ’报表演示’;
b.页脚: ExcelID.ActiveSheet.PageSetup.CenterFooter := ’第&P页’;
c.页眉到顶端边距2cm: ExcelID.ActiveSheet.PageSetup.HeaderMargin := 2/0.035;
d.页脚到底端边距3cm: ExcelID.ActiveSheet.PageSetup.HeaderMargin := 3/0.035;
e.顶边距2cm: ExcelID.ActiveSheet.PageSetup.TopMargin := 2/0.035;
f.底边距2cm: ExcelID.ActiveSheet.PageSetup.BottomMargin := 2/0.035;
g.左边距2cm: ExcelID.ActiveSheet.PageSetup.LeftMargin := 2/0.035;
h.右边距2cm: ExcelID.ActiveSheet.PageSetup.RightMargin := 2/0.035;
i.页面水平居中: ExcelID.ActiveSheet.PageSetup.CenterHorizontally := 2/0.035;
j.页面垂直居中: ExcelID.ActiveSheet.PageSetup.CenterVertically := 2/0.035;
k.打印单元格网线: ExcelID.ActiveSheet.PageSetup.PrintGridLines := True;

15) 拷贝操作:
a.拷贝整个工作表: ExcelID.ActiveSheet.Used.Range.Copy;
b.拷贝指定区域: ExcelID.ActiveSheet.Range[ ’A1:E2’ ].Copy;
c.从A1位置开始粘贴: ExcelID.ActiveSheet.Range.[ ’A1’ ].PasteSpecial;
d.从文件尾部开始粘贴: ExcelID.ActiveSheet.Range.PasteSpecial;

16) 插入一行或一列:
a. ExcelID.ActiveSheet.Rows[2].Insert;
b. ExcelID.ActiveSheet.Columns[1].Insert;

17) 删除一行或一列:
a. ExcelID.ActiveSheet.Rows[2].Delete;
b. ExcelID.ActiveSheet.Columns[1].Delete;

18) 打印预览工作表: ExcelID.ActiveSheet.PrintPreview;

19) 打印输出工作表: ExcelID.ActiveSheet.PrintOut;

20) 工作表保存:
if not ExcelID.ActiveWorkBook.Saved then
ExcelID.ActiveSheet.PrintPreview;

21) 工作表另存为: ExcelID.SaveAs( ’C:\Excel\Demo1.xls’ );

22) 放弃存盘: ExcelID.ActiveWorkBook.Saved := True;

23) 关闭工作簿: ExcelID.WorkBooks.Close;

24) 退出 Excel: ExcelID.Quit;

25)释放VARIANT变量:EX:ExcelApp:=Unassigned;

知道一個excel檔內有多少個WorkSheet
XLAPP.WorkBooks[n].Sheets.Count

知道該Sheet的名稱
XLAPP.WorkBooks[n].Sheets[n].Name

打开第2个工作表
ExcelApp.Worksheets[2].activate;

打开名为第四章的工作表
ExcelApp.WorkSheets['第四章'].activate;

2010年11月11日 星期四

CCIR656與601的不同點

CCIR656與601的不同點 

用最簡單的觀念來說,CCIR656與601的不同點如下:

(1) CCIR656是標準規格,包含8-bit data與一個 CLOCK, 共9 pins, HS and VS則以特定code的形式內藏於data中。
      後端處理時,需先解出HS and VS.
   (應用時,由於是標準,不管是Front Porch, Back Porch,都是標準寬度,任何decoder解出來影像顯示在面板上的位置應該都要相同)

(2) CCIR601非標準規格,常用有8-bit與16-bit形式,另加HS, VS, CLOCK 3 pins。故8-bit mode共11 pins, 16-bit mode共19 pins.
      (應用時,由於非標準,Front Porch, Back Porch寬度可自己定義,因此大家定的有差異時,影像顯示在面板上的位置會有差異)

為減少FPC pin assignment以及免除規格不同所造成的顯示差異,故產品應用時幾乎都採用CCIR656.

另外補充CCIR656/601 (或稱YUV介面)與RGB介面的差異:

CCIR656/601傳輸影像亮度與色差訊號(Y Cb Cr),一般採用4:2:2格式(每傳四個Y,只傳兩個Cb與兩個Cr),用來降低資料傳輸量,以節省頻寬。

例如720RGBX480解析度,RGB介面傳輸資料量即為(720R+720G+720B)X480個,而CCIR656/601傳輸資料量為(720Y+480Cb+480Cr)X480,

資料量僅為RGB介面的2/3.

為何可以將Cb, Cr各丟掉一半呢?因為人眼對亮度較敏感,故Y需全傳,但人眼對顏色較不敏感,故可以丟掉部分資料不傳,

如此解出來的RGB當然會失真,但人眼不易察覺。

4:2:2格式YUV轉RGB時,輸入之YUV資料為

Cb0 Y0 Cr0 Y1 Cb2 Y2 Cr2 Y3 Cb4 Y4 Cr4 Y5 Cb6 Y6 Cr6 Y7............................

=> 輸出為

Pixel 0 (R0, G0, B0)由Cb0, Y0, Cr0轉換出來

Pixel 1 (R1, G1, B1)由Cb0, Y1, Cr0轉換出來

Pixel 2 (R2, G2, B2)由Cb2, Y2, Cr2轉換出來

Pixel 3 (R3, G3, B3)由Cb2, Y3, Cr2轉換出來

以此類推........

以上所述為基本概念,歡迎指教。

若您需要知道的更詳細,可參考附件之Video Demystified一書,謝謝。

昨天在公司看文档的时候,发现sensor部分的接口有两个标准CCIR601和CCIR656。那么CCIR601和CCIR656到底有什么区别和联系呢?
google下 看到以下叙述:
據我所知,這兩種標準都是 video transmission 的 interface,在 video frame format 的規格應該是相同的,也就是每張 frame 是 720x480, YUV 4:2:2 的格式,兩者的差別在於 interface 規格的不同,在 CCIR656 中,有 8 bit 的 data bus 和 clock 的訊號,也就是說 CCIR656 是同步傳輸的,decoder 端不用自己產生 clock。p4zu
在 CCIR601 中,訊號內包含了兩個同步訊號:Horizontal Synchronization 和 Vertical Synchronization,decoder 要自己去鎖定這個同步訊號,再自己產生 clock 來解。所以以 CCIR656 來傳遞的 video 訊號品質應該會好一些吧!gq|
1.基本上 CCIR 656 的 CLK 為 27MHz, DataBus 為 8Bits. .,?X^
CCIR 601 的 CLK 為 13.5MHz,Data為16Bits.~oq%n%
但兩者同為 YUV4:2:2,所以品質是相同的,CCIR 656 需要 9Pins、CCIR 601需要19Pins,所以CCIR 656 DATABUS較省,但CLK 較快.j`
2.CCIR 656 收到DATA後需轉換成 CCIR 601 後再轉換成 YUV4:4:4,且 CLK 需除頻(/2)為 13.5MHz;7
CCIR601 直接將 DATA 轉換成 4:4:4 即可, CLK 不變.*
3.CCIR 656 需從 DATA 中解出 VS、HS, CCIR 601 則直接使用輸入的 VS、HS 即可.W][YU
由於 CCIR 656 PIN 腳較少且 27MHz 的 CLK 對現在的 IC 根本不算快,所以使用 CCIR 656 可能會比較適合.

在《Video Demystified》第四版上,关于601和656是这样解释的。
BT.601    This ITU recommendation specifies the 720 × 480 (59.94 Hz), 960 × 480 ( 59.94 Hz), 720 × 576 (50 Hz), and 960 × 576 (50 Hz) 4:2:2 YCbCr interlaced standards.
BT.656    This ITU recommendation defines a parallel interface (8-bit or 10-bit, 27 MHz)
               and a serial interface (270 Mbps) for the transmission of 4:3 BT.601 4:2:2
               YCbCr digital video between pro-video equipment. Also see SMPTE 125M.
转自http://blog.donews.com/purecy/archive/2005/04/11/331300.aspx

What's the CCIR601
 The following contents come from http://www.wikipedia.org/wiki/CCIR_601
CCIR 601 is the old name of a standard published by the CCIR (now ITU-R) for encoding interlaced analogue video signals in digital form. It includes methods of encoding 525-line 60 Hz and 625-line 50 Hz signals, both with 720 luminance samples and 360 chrominance samples per line. The colour encoding system is known as 4:2:2, that being the ratio of Y:Cb:Cr samples (luminance data:blue chroma data:red chroma data). For a pair of pixels, the data is stored in the order Y1:Y2:Cb:Cr, with the chrominance samples co-sited with the first luminance sample.
The CCIR 601 signal can be reagarded as if it is a digitally encoded analog component video signal, and thus includes data for the horizontal and vertical sync and blanking intervals. Regardless of the frame rate, the luminance sampling frequency is 13.5 MHz. The luminance sample is at least 8 bits, and the chrominance samples are at least 4 bits each.
The first version of CCIR 601 defined only a parallel interface, but later versions introduced the bit-serial versions that are now commonly used. The 8-bit serial protocol (216 Mb/s) was once used in D1 digital tape recording. Modern standards use an encoding table to expand the data to 9 or 10 bits. The 9-bit serial version has a data rate of 243 Mb/s. The 10-bit version used in D5 digital tape recording has a data rate of 270 Mbits/s.
There is an 8-bit version in which only data from the active video periods are transmitted, with a bit rate of only 165.9 Mbit/s.
In each 8-bit luminance sample, the value 16 is used for black and 235 for white, to allow for overshoot and undershoot. The values 0 and 255 are used for sync encoding. The Cb and Cr samples use the value 128 to encode a zero value, as used when encoding a colourless area.
The CCIR 601 video raster format has been re-used in a number of later standards, including MPEG.
CCIR601 defines the sampling systems, matrix values and filter characteristics for both (Y/B-Y/R-Y) and (R/G/B) component of digital television signals.
CCIR656 is "the physical parallel and serial interconnect scheme for CCIR601". CCIR656 defines the parallel connector pinouts as well as the blanking, sync, and multiplexing schemes used in both parallel and serial interface.

收藏自: http://5geshouwang.blog.sohu.com/140738626.html